Introducción

Sin duda alguna los automóviles han sido y son parte esencial de la sociedad, su movilidad y su transporte, desafortunadamente los siniestros causados por ellos son parte inherente de su uso y el impacto de ellos repercute de manera directa o indirecta en la vida de los involucrados, pero también de las personas que los rodean.

De acuerdo con un reporte de la Organización Mundial de la Salud en 2017, los accidentes viales son causantes de más de 1.3 de millones de muertes al año, y un estimado de alrededor de 50 millones de personas con traumatismos no mortales siendo así la quinta causa de los fallecimientos mundiales anuales.

Aunado a lo anterior, la OMS ahonda en su reporte, indicando que el 93% de los accidentes de tránsito suceden en los países de ingresos bajos y medianos. De este 93%, 20% acaece en la región de las Américas, en donde las estadísticas reportan más de 155’000 muertes por año por accidentes automovilísticos.

Por su parte México y de acuerdo con los datos del Instituto Nacional de Salud Pública (INSP), el país se encuentra en el séptimo lugar a nivel mundial en el rubro de siniestros automovilísticos mortales, y ocupa el tercer lugar en la región de Latinoamérica en este mismo rubro

Además de las repercusiones sociales y humanas, los accidentes viales, representan en números un estimado de más de 220 mil millones de pesos en costos, cifra la cual supera el 2% del PIB del país. Eventualmente los costos no son todos absorbidos por las instituciones del gobierno, y es el propio usuario en quién recae la mayor cantidad de responsabilidad económica asociada al siniestro. De nuevo, este último factor es un atenuante para la sociedad puesto que, continuando con los estudios presentados por el INSP, en promedio el gasto por accidente alcanza un costo de alrededor de 25´000 pesos, y si a esto se le suma que derivado de los siniestros automovilísticos se suman alrededor de 50´000 personas al grupo de personas con discapacidad motora, de los cuáles 70% no vuelve a conseguir empleo. Los costos en seguridad social, reparación de daños, entre otros regresan para ser solventados por las instituciones de gobierno.

Bajo este tenor, y con el fin de atenuar la situación descrita anteriormente, resulta útil identificar cuáles son los factores que tienen mayor influencia en los choques automovilísticos, cuáles son los perfiles más propensos a generar un choque, y simultáneamente diseñar estrategias que permitan atacar las causas raíz de los siniestros automovilísticos en México.

Seccion de lectura y Limpieza de datos

Empezamos por descargar los datos necesarios para el analisis lo cuales fueron recabados de la pagina del INEGI, estos se pueden encontrar en los siguientes enlaces:

  • Diccionario de datos: LINK
  • Pagina de los datos: LINK
In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import os
import urllib.request

url="https://www.inegi.org.mx/contenidos/programas/accidentes/datosabiertos/atus_anual_csv.zip"
file_name="atus_anual_1997_2019"
In [2]:
def descarga(url,file_name,n_file=0):
    import requests, zipfile, io,os.path
    if not os.path.exists(file_name):
        r = requests.get(url)
        z = zipfile.ZipFile(io.BytesIO(r.content))
        if n_file==0:
            z.extractall("")
        else:
            z.extractall(file_name)
    return print("Descarga de archivos completa")
In [3]:
descarga(url,file_name)
Descarga de archivos completa

Lectura de los datos pertenecientes a los años 2010 - 2019

In [4]:
from os import listdir

filepaths = [f for f in listdir("atus_anual_1997_2019/conjunto_de_datos") if f.endswith('.csv')]
In [5]:
lista_archivos=list(map(lambda x: "atus_anual_1997_2019/conjunto_de_datos/"+x, sorted(filepaths,reverse=True)[:10]))
In [6]:
df = pd.concat(map(lambda archivo: pd.read_csv(archivo,index_col=False),lista_archivos))

Dataset Original perteneciente a accidentes en todo Mexico del 2010 al 2019

In [7]:
df.shape
Out[7]:
(3841493, 45)

Tras la conjunción de todos los archivos obtuvimos un dataframe con 45 campos y 3,841,493 registros

In [8]:
df.head()
Out[8]:
COBERTURA ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA DIASEMANA URBANA ... PEATMUERTO PEATHERIDO CICLMUERTO CICLHERIDO OTROMUERTO OTROHERIDO NEMUERTO NEHERIDO CLASACC ESTATUS
0 Municipal 1 1 2019 1 1 5 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 0 No fatal Cifras Definitivas
1 Municipal 1 1 2019 1 3 53 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 0 No fatal Cifras Definitivas
2 Municipal 1 1 2019 1 5 35 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas
3 Municipal 1 1 2019 1 6 50 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas
4 Municipal 1 1 2019 1 8 50 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas

5 rows × 45 columns

Para la acotación correspondiente a nuestro proyecto, Filtramos los datos pertenecientes a la Ciudad de Mexico cuyo codigo de entidad es 9

In [9]:
df_cdmx = df[df.ID_ENTIDAD==9]
df_cdmx = df_cdmx.reset_index(drop=True)
In [10]:
df_cdmx.shape
Out[10]:
(136812, 45)

Tras el filtro para seleccionar únicamente a la CDMX, se obtuvo un datframe más pequeño con 136,812 registros. Continuando con el análisis exploratorio de los datos, examinamos el nombre de las columnas de la siguiente forma

In [11]:
df_cdmx.columns
Out[11]:
Index(['COBERTURA', 'ID_ENTIDAD', 'ID_MUNICIPIO', 'ANIO', 'MES', 'ID_HORA',
       'ID_MINUTO', 'ID_DIA', 'DIASEMANA', 'URBANA', 'SUBURBANA', 'TIPACCID',
       'AUTOMOVIL', 'CAMPASAJ', 'MICROBUS', 'PASCAMION', 'OMNIBUS', 'TRANVIA',
       'CAMIONETA', 'CAMION', 'TRACTOR', 'FERROCARRI', 'MOTOCICLET',
       'BICICLETA', 'OTROVEHIC', 'CAUSAACCI', 'CAPAROD', 'SEXO', 'ALIENTO',
       'CINTURON', 'ID_EDAD', 'CONDMUERTO', 'CONDHERIDO', 'PASAMUERTO',
       'PASAHERIDO', 'PEATMUERTO', 'PEATHERIDO', 'CICLMUERTO', 'CICLHERIDO',
       'OTROMUERTO', 'OTROHERIDO', 'NEMUERTO', 'NEHERIDO', 'CLASACC',
       'ESTATUS'],
      dtype='object')

A continuación se muestra la descrpición de los campos, la cual nos ayuda a entender mejor el significado de los datos de cada columnna.

In [12]:
diccionario_datos=pd.read_csv("atus_anual_1997_2019/diccionario_de_datos/diccionario_de_datos_atus_anual_1997_2019.csv",
                              index_col="COLUMNA",usecols=[0, 1])
diccionario_datos.head()
Out[12]:
DESCRIPCION
COLUMNA
COBERTURA Área geográfica a la que están referidos los i...
ID_ENTIDAD Clave de la entidad federativa según el Catálo...
ID_MUNICIPIO Clave del municipio según el Catálogo de Entid...
ANIO Los cuatro dígitos correspondientes al año en ...
MES Correspondiente al mes de referencia en que oc...

Lista de los campos y su descripción.

In [13]:
def imprimir_descripcion(df, width):
    with pd.option_context('display.max_colwidth', width):
        print(df)

imprimir_descripcion(diccionario_datos, 800)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  DESCRIPCION
COLUMNA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
COBERTURA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Área geográfica a la que están referidos los indicadores estadísticos
ID_ENTIDAD                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Clave de la entidad federativa según el Catálogo de Entidades, Municipios y Localidades del INEGI
ID_MUNICIPIO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Clave del municipio según el Catálogo de Entidades, Municipios y Localidades del INEGI
ANIO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Los cuatro dígitos correspondientes al año en que ocurrió el accidente
MES                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Correspondiente al mes de referencia en que ocurrió el accidente 
ID_HORA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          La hora (sin los minutos) en que ocurrió el accidente, con rango: 00-23 horas. Clave 99 Hora no especificada
ID_MINUTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Los minutos en que ocurrió el accidente, con rango: 00-59. Clave 99 Minutos no especificados
ID_DIA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Número correspondiente al día del mes en que ocurrió el accidente, con rango: 01 a 28, 30 ó 31 según corresponda al mes de referencia. Clave 32 Día no especificado.
DIASEMANA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     El día de la semana en que ocurrió el accidente
URBANA                                                                                                                                                                                                                  Es el área habitada o urbanizada que partiendo de un núcleo central, presenta continuidad física en todas direcciones hasta ser interrumpida, en forma notoria, por terrenos de uso no urbano como bosques, sembradíos o cuerpos de agua. Se caracteriza por presentar asentamientos humanos concentrados de más de 15,000 habitantes. En estas áreas, se asienta la administración pública, el comercio organizado y la industria. Cuenta con infraestructura, equipamiento y servicios urbanos, tales como drenaje, energía eléctrica, red de agua potable, escuelas, hospitales, áreas verdes y de diversión, etc.
SUBURBANA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Son aquellas zonas donde la población es de 2,500 a 14,999 habitantes, las viviendas se encuentran dispersas y en algunas ocasiones carecen de algunos servicios.
TIPACCID      Corresponda al tipo de accidente de tránsito, de acuerdo con las siguientes descripciones: 1) Colisión con vehículo automotor: Encuentro violento, accidental o imprevisto de dos o más vehículos en una vía de circulación, del cual resultan averías, daños, pérdida  parcial o total de vehículos o propiedades, así como lesiones leves y/o fatales a personas. Puede ser lateral, frontal o por alcance. 2) Colisión con peatón: Evento vial donde un vehículo de motor arrolla o golpea a una persona que transita o que se encuentra en alguna vía pública, provocando lesiones leves o fatales. 3) Colisión con animal: Es aquel accidente en el que un vehículo de motor arrolla a cualquier  tipo de animal provocando daños materiales, inclusive lesiones leves o fatales a personas ocupantes o no del vehículo...
AUTOMOVIL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Automóvil. Comprende los vehículos de motor destinados principalmente al transporte de personas, que cuentan hasta con 7 asientos (incluyendo el del conductor).
CAMPASAJ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Camioneta de pasajeros. comprende todos los vehículos de motor destinados primordialmente al transporte de personas y que tengan de 8 a 15 asientos (incluyendo el del conductor).
MICROBUS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Microbus. Autobús de menor tamaño usado por lo general en el transporte urbano de pasajeros y que tenga de 16 a 20 asientos (incluyendo el del conductor).
PASCAMION                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Camión urbano de pasajeros. Comprende los autobuses urbanos y suburbanos y en general los vehículos que tengan de 21 a 29 asientos, destinados al transporte público y privado de personas, los cuales cuentan con rutas fijas.
OMNIBUS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Omnibús. Comprende los vehículos automotores con 30 o más asientos, destinados al transporte público y privado de personas, con destinos establecidos, así como horarios de llegada y salida.
TRANVIA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Tren eléctrico o trolebús. Comprende los vehículos de motor destinados al transporte de personas, propulsados por energía eléctrica captada de cables aéreos, que no circulan sobre rieles (este tipo de transporte sólo se encuentra registrado en el Ciudad de México y Guadalajara).
CAMIONETA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Camioneta de carga. Son aquellas que están destinadas exclusivamente al transporte de carga; se identifican de acuerdo al tamaño y a la capacidad de hasta 999 kilogramos.
CAMION                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Camión de carga. Comprende los vehículos de propulsión mecánica propia, destinados exclusiva o principalmente al transporte de carga, con capacidad de 1,000 hasta 5,000 kilogramos.
TRACTOR                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tractor con o sin remolque. Comprende los vehículos de propulsión mecánica propia, diseñados exclusiva o principalmente para remolcar otros vehículos (excluye los tractores agrícolas, industriales y de construcción).
FERROCARRI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Ferrocarril. Medio de transporte sobre rieles para el transporte de pasajeros y carga, que recorre distancias relativamente largas a velocidades medias.
MOTOCICLET                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Motocicleta. Vehículo automotor de dos, tres o cuatro ruedas, cuyo peso no excede los 400 kilogramos.
BICICLETA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Bicicleta. Vehículo de dos o tres ruedas generalmente iguales, movidas por pedales y una cadena, el cual es propulsado por el esfuerzo humano.
OTROVEHIC                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 Otro. Considérese cualquier otro tipo de vehículo no descrito en la clasificación anterior; por ejemplo las ambulancias, grúas, vehículos de tracción animal o humana, carro de bomberos, tractores agrícolas, industriales y de construcción, etc.
CAUSAACCI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   La causa presunta o determinante puede considerarse como: El motivo principal que causó el accidente, ya sea por condiciones inseguras o actos irresponsables potencialmente prevenibles, atribuidos a conductores de vehículos, así como a peatones o pasajeros, falla de vehículos, condiciones del camino, circunstancias climatológicas, etc.
CAPAROD                                                                                                                                                                                                                                                                                                                                                                                                                           Superficie de rodamiento en donde ocurrió el accidente de tránsito. Pavimentada Conjunto de capas de material rígido (concreto hidráulico) o flexible (carpeta asfáltica) compactado sobre el subsuelo, que permite el tránsito adecuado de vehículos y su carga. No pavimentada. Camino acondicionado con materiales naturales (piedra, bola, tezontle, etc.), para el tránsito de vehículos y/o personas.
SEXO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Genero del conductor presunto responsable de ocasionar el accidente.
ALIENTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Sobriedad del conductor presunto responsable del accidente
CINTURON                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      El Conductor presunto responsable del accidentes usaba el Cinturón de seguridad
ID_EDAD                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 La edad del conductor presunto responsable, la cual debe estar anotada con un número arábigo de 12 a 98. La clave 0 se refiere a los registros en donde el conductor se fugó y los registros con  clave 99 se refiere Se ignora la edad del conductor
CONDMUERTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Número de conductores del automóvil, camioneta de pasajeros, microbús, camión urbano de pasajeros, ómnibus, tren eléctrico o trolebús, camioneta de carga, camión de carga, tractor con o sin remolque, ferrocarril o motocicleta involucrado, que a consecuencia del evento muere en el lugar del accidente.
CONDHERIDO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Número de conductores heridos del automóvil, camioneta de pasajeros, microbús, camión urbano de pasajeros, ómnibus, tren eléctrico o trolebús, camioneta de carga, camión de carga, tractor con o sin remolque, ferrocarril o motocicleta involucrados, que resulta heridos a consecuencia del accidente.
PASAMUERTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Número de personas que son transportadas en algún vehículo de motor, sin considerar al conductor, que a consecuencia del evento muere en el lugar del accidente.
PASAHERIDO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Número de personas que son transportadas en algún vehículo de motor, sin considerar al conductor, que resulta heridos a consecuencia del accidente.
PEATMUERTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Número de personas que transita por sus propios medios de locomoción por alguna calle, avenida, boulevard, glorieta, etc., que a consecuencia del evento muere en el lugar del accidente.
PEATHERIDO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Número de personas que transita por sus propios medios de locomoción por alguna calle, avenida, boulevard, glorieta, etc. que resulta heridos a consecuencia del accidente.
CICLMUERTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Número de personas que va operando o circulando en alguna bicicleta, triciclo, etc., que a consecuencia del evento muere en el lugar del accidente.
CICLHERIDO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Número de personas que va operando o circulando en alguna bicicleta, triciclo, etc. que resulta heridos a consecuencia del accidente.
OTROMUERTO                                                                                                                                                                                                                                                                                                                                        Número de personas que indirectamente estuvieron involucrados en el accidente y que por su naturaleza no pueden ser incluidas en la clasificación señalada  anteriormente, tales como personas que se encuentran en el interior de casas, negocios, comercios, así como todos aquellos individuos que por cuestiones laborales realizan actividades de mantenimiento, limpieza y/o construcción de las vías de comunicación, que a consecuencia del evento muere en el lugar del accidente.
OTROHERIDO                                                                                                                                                                                                                                                                                                                                                     Número de personas que indirectamente estuvieron involucrados en el accidente y que por su naturaleza no pueden ser incluidas en la clasificación señalada  anteriormente, tales como personas que se encuentran en el interior de casas, negocios, comercios, así como todos aquellos individuos que por cuestiones laborales realizan actividades de mantenimiento, limpieza y/o construcción de las vías de comunicación, que resulta heridos a consecuencia del accidente.
NEMUERTO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Número de víctimas muertas en las cuales la fuente informante no realizó la clasificación, que a consecuencia del evento muere en el lugar del accidente.
NEHERIDO                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Corresponde a las víctimas heridas en las cuales la fuente informante no realizó la clasificación,  que resulta heridos a consecuencia del accidente.
CLASACC                                                                                                                                                                                                                                                                                                                                                                              Los accidentes se clasifican en Fatales: Se refiere a todo accidente de tránsito en el cual una o más personas fallecen en el lugar del evento; No fatales: Se refiere a todo accidente de tránsito en el cual una o más personas resultan con lesiones con o sin consecuencia de muerte y Sólo daños: Se refiere a todo accidente en el que se ocasionaron daños materiales a vehiculos automotores, propiedad del estado, inmueble particular y otros.
ESTATUS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Estatus de las cifras conforme a los Lineamientos de Cambios a la información divulgada en las publicaciones estadísticas y geográficas del INEGI

Igualmente de la siguiente forma podemos elegir el nombre de la columna de la cual queremos obtener la descripcion

In [14]:
list(diccionario_datos.loc["ID_MUNICIPIO"])
Out[14]:
['Clave del municipio según el Catálogo de Entidades, Municipios y Localidades del INEGI']

Examinando la Columna ID_MUNICIPIO podemos observar que son solo numeros, por lo cuel seria mejor trabajar con nombre de los municipios en lugar de numero. Por lo cual cambiaremos esta columna. Para lograrlo importamos la informacion perteneciente al nombre del municipio asociado con su ID.

In [15]:
#Lectura del nombre pertenecientes a las delegaciones
delegacion_nombre=pd.read_csv("atus_anual_1997_2019/catalogos/tc_municipio.csv",index_col=False)

Examinando el archivo podemos observar que son solo 3 columnas por lo cual filtramos los datos para obtener solo los municipios pertencecientes a la CDMX los cuales deben de ser 16

In [16]:
delegacion_nombre=delegacion_nombre[(delegacion_nombre.ID_ENTIDAD==9)&(delegacion_nombre.ID_MUNICIPIO!=999)]
delegacion_nombre.head()
Out[16]:
ID_ENTIDAD ID_MUNICIPIO NOM_MUNICIPIO
278 9 2 Azcapotzalco
279 9 3 Coyoacán
280 9 4 Cuajimalpa de Morelos
281 9 5 Gustavo A. Madero
282 9 6 Iztacalco

Agregamos el nombre de las delegaciones al Dataframe que estamos manejando

In [17]:
df_cdmx=df_cdmx.merge(delegacion_nombre[['ID_MUNICIPIO', 'NOM_MUNICIPIO']], how='left', on='ID_MUNICIPIO')
In [18]:
df_cdmx.head()
Out[18]:
COBERTURA ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA DIASEMANA URBANA ... PEATHERIDO CICLMUERTO CICLHERIDO OTROMUERTO OTROHERIDO NEMUERTO NEHERIDO CLASACC ESTATUS NOM_MUNICIPIO
0 Municipal 9 2 2019 1 19 59 1 Martes Accidente en intersección ... 0 0 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco
1 Municipal 9 2 2019 1 3 37 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco
2 Municipal 9 2 2019 1 14 23 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco
3 Municipal 9 2 2019 1 15 55 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco
4 Municipal 9 2 2019 1 14 30 9 Miercoles Accidente en intersección ... 0 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco

5 rows × 46 columns

Examinando las columnas observamos que existen columnas separadas para los elementos de pertenecientes a fecha del accidente. Es decir, existe una columna para año, otra para mes, dia, etc. Por lo cual seria adecuado combinar estas columnas para obtener la fecha completa en la cual el accidente tuvo lugar

In [19]:
df_cdmx = df_cdmx.reset_index(drop=True)
concatenar = lambda anio,mes,dia,hora,minu: str(anio)+"/"+str(mes)+"/"+str(dia)+" "+ str(hora)+":"+str(minu)
df_cdmx["FECHA"] = list(map(concatenar,df_cdmx.ANIO,df_cdmx.MES,df_cdmx.ID_DIA,df_cdmx.ID_HORA,df_cdmx.ID_MINUTO))
df_cdmx["FECHA"] = pd.to_datetime(df_cdmx["FECHA"]) 
df_cdmx.head(5)
Out[19]:
COBERTURA ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA DIASEMANA URBANA ... CICLMUERTO CICLHERIDO OTROMUERTO OTROHERIDO NEMUERTO NEHERIDO CLASACC ESTATUS NOM_MUNICIPIO FECHA
0 Municipal 9 2 2019 1 19 59 1 Martes Accidente en intersección ... 0 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-01 19:59:00
1 Municipal 9 2 2019 1 3 37 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-05 03:37:00
2 Municipal 9 2 2019 1 14 23 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-05 14:23:00
3 Municipal 9 2 2019 1 15 55 5 Sabado Accidente en intersección ... 0 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-05 15:55:00
4 Municipal 9 2 2019 1 14 30 9 Miercoles Accidente en intersección ... 0 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-09 14:30:00

5 rows × 47 columns

Despues de realizar los pasos anteriores hemos agregado mas columnas a nuestro dataset, por lo cual empezaremos a revisarlas, para ver que no haya errores ni NaNs.

In [20]:
df_cdmx.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 136812 entries, 0 to 136811
Data columns (total 47 columns):
 #   Column         Non-Null Count   Dtype         
---  ------         --------------   -----         
 0   COBERTURA      136812 non-null  object        
 1   ID_ENTIDAD     136812 non-null  int64         
 2   ID_MUNICIPIO   136812 non-null  int64         
 3   ANIO           136812 non-null  int64         
 4   MES            136812 non-null  int64         
 5   ID_HORA        136812 non-null  int64         
 6   ID_MINUTO      136812 non-null  int64         
 7   ID_DIA         136812 non-null  int64         
 8   DIASEMANA      136812 non-null  object        
 9   URBANA         136812 non-null  object        
 10  SUBURBANA      136812 non-null  object        
 11  TIPACCID       136812 non-null  object        
 12  AUTOMOVIL      136812 non-null  int64         
 13  CAMPASAJ       136812 non-null  int64         
 14  MICROBUS       136812 non-null  int64         
 15  PASCAMION      136812 non-null  int64         
 16  OMNIBUS        136812 non-null  int64         
 17  TRANVIA        136812 non-null  int64         
 18  CAMIONETA      136812 non-null  int64         
 19  CAMION         136812 non-null  int64         
 20  TRACTOR        136812 non-null  int64         
 21  FERROCARRI     136812 non-null  int64         
 22  MOTOCICLET     136812 non-null  int64         
 23  BICICLETA      136812 non-null  int64         
 24  OTROVEHIC      136812 non-null  int64         
 25  CAUSAACCI      136812 non-null  object        
 26  CAPAROD        136812 non-null  object        
 27  SEXO           136812 non-null  object        
 28  ALIENTO        136812 non-null  object        
 29  CINTURON       136812 non-null  object        
 30  ID_EDAD        136812 non-null  int64         
 31  CONDMUERTO     136812 non-null  int64         
 32  CONDHERIDO     136812 non-null  int64         
 33  PASAMUERTO     136812 non-null  int64         
 34  PASAHERIDO     136812 non-null  int64         
 35  PEATMUERTO     136812 non-null  int64         
 36  PEATHERIDO     136812 non-null  int64         
 37  CICLMUERTO     136812 non-null  int64         
 38  CICLHERIDO     136812 non-null  int64         
 39  OTROMUERTO     136812 non-null  int64         
 40  OTROHERIDO     136812 non-null  int64         
 41  NEMUERTO       136812 non-null  int64         
 42  NEHERIDO       136812 non-null  int64         
 43  CLASACC        136812 non-null  object        
 44  ESTATUS        136812 non-null  object        
 45  NOM_MUNICIPIO  136812 non-null  object        
 46  FECHA          136812 non-null  datetime64[ns]
dtypes: datetime64[ns](1), int64(33), object(13)
memory usage: 49.1+ MB

Observando el dataset podemos notar que no tenemos valores nulos o NaNs. De igual forma muchas columnas estan en formato object, por lo cual en su mayoria son texto. Analizando la documentacion perteneciente al Dataset, sabemos que la mayoria de columnas del tipo object pertenecen a datos del tipo categorico, por lo cual las opciones son limitadas. Examinando estas columnas podriamos encontrar algun error en el momento de su captura.

In [21]:
columnas_object=df_cdmx[['COBERTURA', 'DIASEMANA','URBANA','SUBURBANA','TIPACCID',
         'CAUSAACCI','CAPAROD','SEXO','ALIENTO','CINTURON','CLASACC',
         'ESTATUS','NOM_MUNICIPIO']] 

Mediante la siguiente funcion podemos examinar con mas detalle los valores unicos de cada columna tipo object

In [22]:
def rstr(df): return df.apply(lambda x: [x.unique()])

imprimir_descripcion(rstr(columnas_object), 800)
     COBERTURA  \
0  [Municipal]   

                                                                                DIASEMANA  \
0  [Martes, Sabado, Miercoles, Jueves, Viernes, lunes, Domingo, Miércoles, Lunes, Sábado]   

                                                                                  URBANA  \
0  [Accidente en intersección, Accidente en no intersección, Sin accidente en esta zona]   

                                                                                                            SUBURBANA  \
0  [Sin accidente en esta zona, Accidentes en otro camino, Accidente en carretera estatal, Accidente en camino rural]   

                                                                                                                                                                                                                                                              TIPACCID  \
0  [Colisión con motocicleta, Colisión con vehículo automotor, Colisión con objeto fijo, Colisión con peatón (atropellamiento), Colisión con ciclista, Otro, Caída de pasajero, Volcadura, Salida del camino, Incendio, Colisión con ferrocarril, Colisión con animal]   

                                                                             CAUSAACCI  \
0  [Conductor, Otra, Mala condición del camino, Peatón o pasajero, Falla del vehículo]   

                         CAPAROD                      SEXO  \
0  [Pavimentada, No Pavimentada]  [Hombre, Se fugó, Mujer]   

               ALIENTO             CINTURON                        CLASACC  \
0  [No, Se ignora, Sí]  [Se ignora, Sí, No]  [No fatal, Sólo daños, Fatal]   

                                  ESTATUS  \
0  [Cifras Definitivas, Cifras Revisadas]   

                                                                                                                                                                                                                                 NOM_MUNICIPIO  
0  [Azcapotzalco, Coyoacán, Cuajimalpa de Morelos, Gustavo A. Madero, Iztacalco, Iztapalapa, La Magdalena Contreras, Milpa Alta, Álvaro Obregón, Tláhuac, Tlalpan, Xochimilco, Benito Juárez, Cuauhtémoc, Miguel Hidalgo, Venustiano Carranza]  

Podemos observar que en la columna de dias, existen errores de captura ya que existe Sabado y Sábado, por lo cual corregiremos esto.

In [23]:
map_value={"Sábado":"Sabado",
           "Miércoles":"Miercoles",
           "lunes":"Lunes"
          }
df_cdmx['DIASEMANA']=df_cdmx['DIASEMANA'].map(map_value).fillna(df_cdmx['DIASEMANA'])
In [24]:
df_cdmx['DIASEMANA'].unique()
Out[24]:
array(['Martes', 'Sabado', 'Miercoles', 'Jueves', 'Viernes', 'Lunes',
       'Domingo'], dtype=object)

Una vez analizadas las columnas object, analizaremos las columnas numericas mediante la instruccion describe

In [25]:
df_cdmx.describe()
Out[25]:
ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA AUTOMOVIL CAMPASAJ MICROBUS ... PASAMUERTO PASAHERIDO PEATMUERTO PEATHERIDO CICLMUERTO CICLHERIDO OTROMUERTO OTROHERIDO NEMUERTO NEHERIDO
count 136812.0 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 ... 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.000000 136812.0 136812.0
mean 9.0 9.999744 2014.101533 6.599597 12.743634 20.982655 15.497259 1.355758 0.164284 0.048738 ... 0.002902 0.075688 0.010584 0.069402 0.000468 0.008347 0.000219 0.001118 0.0 0.0
std 0.0 4.935364 2.821343 3.401673 6.391080 17.686245 8.732645 0.738808 0.412503 0.221941 ... 0.062467 0.437005 0.104103 0.279112 0.021959 0.092653 0.014807 0.037151 0.0 0.0
min 9.0 2.000000 2010.000000 1.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0
25% 9.0 5.000000 2012.000000 4.000000 8.000000 0.000000 8.000000 1.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0
50% 9.0 10.000000 2014.000000 7.000000 13.000000 20.000000 15.000000 1.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0
75% 9.0 15.000000 2017.000000 10.000000 18.000000 30.000000 23.000000 2.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0
max 9.0 17.000000 2019.000000 12.000000 23.000000 59.000000 31.000000 9.000000 5.000000 3.000000 ... 5.000000 26.000000 2.000000 7.000000 2.000000 4.000000 1.000000 3.000000 0.0 0.0

8 rows × 33 columns

Analizando la informacion podemos observar que las columnas pertenecientes a numero de muertos (NEMUERTO) y numero de heridos (NEHERIDO) estan llenas de ceros, por lo cual se podrian depurar del set de datos.

De igual forma, las columnas PASAHERIDO,PEATMUERTO,PEATHERIDO,CICLMUERTO,CICLHERIDO,OTROMUERTO,OTROHERIDO estan en su mayoria llenas de ceros de acuerdo a lo que observamos ya que el 75% de los datos (tercer quartil) son 0. Podria ser buena idea depurarlos, sin embargo podrian ser de utilidad para analizis posteriores, por lo cual se conservaran

In [26]:
df_cdmx=df_cdmx.drop(['NEMUERTO',"NEHERIDO"], axis=1)
In [27]:
#generacion del archivo de salida
#compression_opts = dict(method='zip',archive_name='Accidentes_vehiculares_cdmx.csv') 
#df_cdmx.to_csv("Accidentes_vehiculares_cdmx.zip",compression=compression_opts)

Seccion de Transformacion y Preguntas acerca de los datos

Una vez arreglados los datos podemos empezar a realizar algunas preguntas referentes a ellos. Para este proceso se realizo un Brainstorming con el fin de registrar la mayor cantidad de preguntas derivadas de la observación de nuestros datos, este ejercicio permitió empatar preguntas claves por grupos y tras la evualación final, se llego a la obtención de las preguntas que veremos a continuación.

¿Que delegacion/municipio resgistro mas accidentes?

Podemos conocer esto haciendo una agrupacion por Delegacion y en base al año y ordenandola de manera descendiente en base a la delegacion y el año

In [28]:
delagacion_accidentes=df_cdmx.groupby("NOM_MUNICIPIO")["ANIO"].value_counts()
delagacion_accidentes.sort_index(level=['NOM_MUNICIPIO','ANIO'],inplace=True)
delagacion_accidentes.head(30)
Out[28]:
NOM_MUNICIPIO  ANIO
Azcapotzalco   2010     651
               2011     760
               2012     754
               2013     668
               2014     692
               2015     598
               2016     512
               2017     482
               2018     441
               2019     492
Benito Juárez  2010    1433
               2011    1508
               2012    1422
               2013    1291
               2014    1133
               2015     934
               2016     847
               2017     979
               2018     934
               2019     837
Coyoacán       2010    1214
               2011    1586
               2012    1448
               2013    1247
               2014    1071
               2015    1032
               2016     897
               2017     993
               2018     929
               2019     736
Name: ANIO, dtype: int64

Resulta un poco dificil de analizar los datos, podemos graficarlos para analizarlos mejor de la siguiente manera

In [29]:
# Librearia necesaria para usar ggplor en python
#!pip install plotnine
from plotnine import *

%matplotlib inline
In [30]:
df_gra=df_cdmx.groupby(["NOM_MUNICIPIO","ANIO"]).size()#["FECHA_DIA"].value_counts()
df_gra=df_gra.reset_index()
df_gra.columns =["Municipio","Año","count"]
df_gra
Out[30]:
Municipio Año count
0 Azcapotzalco 2010 651
1 Azcapotzalco 2011 760
2 Azcapotzalco 2012 754
3 Azcapotzalco 2013 668
4 Azcapotzalco 2014 692
... ... ... ...
155 Álvaro Obregón 2015 669
156 Álvaro Obregón 2016 598
157 Álvaro Obregón 2017 678
158 Álvaro Obregón 2018 933
159 Álvaro Obregón 2019 786

160 rows × 3 columns

In [31]:
plt.style.use('seaborn')
sns.set(font_scale=1.5)
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot()
sns.barplot(x="Municipio",y="count", ax=ax, palette='husl',hue="Año",data=df_gra);
ax.set_ylabel('Numero de Accindentes')
ax.set_title('Histograma de Accidentes por Delegacion y año')
ax.set_xticklabels(ax.get_xticklabels(), rotation=85)


plt.legend(title="Año",bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.);

De manera grafica se puede analizar un poco mejor los daTos y podemos observar las delegaciones con mas accidentes, las cuales son las delegaciones Cuauhtémoc,Iztapalapa y Gustavo A. Madero. Para tener un panorama mas claro podemos hacer otros analis de los datos, por ejemplo realizar un historgrama de los accidentes totales del 2010 al 2019 de acuerdo a la delegacion.

In [32]:
df_out=df_cdmx.groupby("NOM_MUNICIPIO").size().sort_values(ascending=False)

#df_out.to_csv("df.csv")
In [33]:
df_graph=df_cdmx.groupby("NOM_MUNICIPIO").size().sort_values(ascending=False)
sns.set_style('whitegrid')
fig = plt.figure(figsize=(8, 8))
sns.set(font_scale=1.2)
sns.set_style('white')
ax = sns.barplot(df_graph.values,df_graph.index)
ax.set_title("Histograma de Accidentes totales por Delegacion")
ax.set(xlabel="Accidentes")
ax.set(ylabel="Municipio");

Adicionalmente podemos realizar un mapa cloroplético para visualizar mejor el porcentaje de accidentes totales entre el año 2010 al 2019

In [34]:
!pip install folium
import folium
Requirement already satisfied: folium in c:\users\sergio\anaconda3\lib\site-packages (0.12.1)
Requirement already satisfied: jinja2>=2.9 in c:\users\sergio\anaconda3\lib\site-packages (from folium) (2.10.1)
Requirement already satisfied: numpy in c:\users\sergio\anaconda3\lib\site-packages (from folium) (1.19.1)
Requirement already satisfied: branca>=0.3.0 in c:\users\sergio\anaconda3\lib\site-packages (from folium) (0.4.2)
Requirement already satisfied: requests in c:\users\sergio\anaconda3\lib\site-packages (from folium) (2.22.0)
Requirement already satisfied: MarkupSafe>=0.23 in c:\users\sergio\anaconda3\lib\site-packages (from jinja2>=2.9->folium) (1.1.1)
Requirement already satisfied: idna<2.9,>=2.5 in c:\users\sergio\anaconda3\lib\site-packages (from requests->folium) (2.8)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\sergio\anaconda3\lib\site-packages (from requests->folium) (2020.12.5)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\sergio\anaconda3\lib\site-packages (from requests->folium) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\users\sergio\anaconda3\lib\site-packages (from requests->folium) (1.24.2)
In [35]:
df_graph=df_graph.reset_index()
df_graph.columns =["Municipio","count"]

Para realizar el mapa cloropletico es necesario conseguir los datos GeoJson, los cuales son datos para el mapeo de las delegaciones, es decir son datos geograficos. Estos datos se encuentran en el dataset MX-CMX.json el cual esta en la misma carpeta que este Jupyter Notebook

In [36]:
#El archivo MX-CMX.json contiene los poligonos necesarios para graficar las delegaciones 
state_data=df_graph
state_data.loc[7,'Municipio']="Alvaro Obregón"
state_data.loc[14,'Municipio']="Magdalena Contreras"
state_data
Out[36]:
Municipio count
0 Cuauhtémoc 17723
1 Iztapalapa 17647
2 Gustavo A. Madero 17130
3 Miguel Hidalgo 12319
4 Benito Juárez 11318
5 Coyoacán 11153
6 Venustiano Carranza 10102
7 Alvaro Obregón 9134
8 Tlalpan 8532
9 Azcapotzalco 6050
10 Iztacalco 5660
11 Xochimilco 3014
12 Cuajimalpa de Morelos 2422
13 Tláhuac 1991
14 Magdalena Contreras 1796
15 Milpa Alta 821
In [37]:
import json
#Revisando el GeoJson data para encontrar en que llave esta guardado el nombre de la delegacion
with open("MX-CMX.json",encoding="utf8") as f: 
    #map_data = f.readlines()
    s = f.read()
    s = s.replace('\t','')
    s = s.replace('\n','')
    s = s.replace(',}','}')
    s = s.replace(',]',']')
    data = json.loads(s)
data['features'][0]["properties"]["NAME_2"]
Out[37]:
'Alvaro Obregón'
In [38]:
#Creando una lista con el nombre de los municipios extraidos en los GeoJson en el orden que aparecen
json_map_file = []
for i in range(len(data['features'])):
    json_map_file.append(data['features'][i]['properties']['NAME_2'])
json_map_file = pd.DataFrame({'Municipio': json_map_file})
In [39]:
#Combinando los datos, para poder obtener los valores del numero de accidentes en el orden del GeoJson
mun_mapping = json_map_file.merge(state_data, on='Municipio')
#mun_mapping
In [40]:
#Creando una columna de datos que contenga el nombre del municipio asi como el porcentaje de accidentes.
mun_mapping["Percent"]=mun_mapping["Municipio"]+": "+((mun_mapping['count']/mun_mapping['count'].sum()) * 100).map(lambda x:str(round(x,2))+"%")
#[data['features'][idx]['properties']['tooltip1']=tooltip_text[idx] for x in mun_mapping["Percent"]]
for idx in range(len(mun_mapping["Percent"])):
    data['features'][idx]['properties']['tooltip1'] = mun_mapping["Percent"][idx]
#    map_data['features'][idx]['properties']['tooltip2'] = tooltip_text2[idx]
In [41]:
#Verificando que se haya creando el valor de la llave en el archivo Json
print(data['features'][0]['properties'])
{'stroke': '#ff0000', 'stroke-opacity': 1, 'fill-opacity': 0, 'NAME_0': 'Mexico', 'NAME_1': 'Distrito Federal', 'NAME_2': 'Alvaro Obregón', 'tooltip1': 'Alvaro Obregón: 6.68%'}
In [42]:
#Grafico Iteractivo 

bins = list(state_data["count"].quantile([0, 0.25, 0.5, 0.75, 1]))
m = folium.Map(location=[19.32847, -99.12766],tiles='cartodbpositron', zoom_start=10,width='80%', height='80%')
 
folium.Choropleth(
    geo_data=data,
    name='choropleth',
    data=state_data,
    columns=['Municipio', 'count'],
    key_on='feature.id',
    fill_color='BuPu',
    fill_opacity=0.7,
    line_opacity=0.5,
    legend_name='Numero de accidentes',
    bins=bins,
    reset=True,
).add_to(m)

#folium.Marker(
#    location=[19.5040652077,-99.1158642087],
#    popup="Mt. Hood Meadows",
#    icon=folium.Icon(icon="cloud"),
#).add_to(m)

folium.LayerControl().add_to(m)

style_function = lambda x: {'fillColor': '#ffffff', 
                            'color':'#000000', 
                            'fillOpacity': 0.1, 
                            'weight': 0.1}
highlight_function = lambda x: {'fillColor': '#000000', 
                                'color':'#000000', 
                                'fillOpacity': 0.50, 
                                'weight': 0.1}
NIL = folium.features.GeoJson(
    data,
    style_function=style_function, 
    control=False,
    highlight_function=highlight_function, 
    tooltip=folium.features.GeoJsonTooltip(['tooltip1'] ,labels=False) 
    
)
m.add_child(NIL)
m.keep_in_front(NIL)
folium.LayerControl().add_to(m)
m
Out[42]:
Make this Notebook Trusted to load map: File -> Trust Notebook

De acuerdo a lo obtenido podemos comprobar las delegaciones con mas accidentes, en especial la delegacion Cuauhtemoc la cual registra los mayores accidentes. Seguido de ella se encuentra la delegación de Iztapalapa y Gustavo A. Madero. Por su parte las delegaciones de Cuajimalpa de Morelos, La Magdalena Contreras y Milpa Alta son las delegaciones con menos choques.

Tras realizar esta gráfica, concluimos que sería interesante también comparar la cantidad de vehiculos y población por delegación, con el fin de ahondar en el análisis.

¿Cual es el promedio de accidentes por delegacion del año 2010 a 2019?

Seria Interesante saber los accidentes promedio de acuerdo a cada delegacion, por lo cual realizaremos lo siguiente mediante la funcion groupby

In [43]:
av_e=df_cdmx.groupby("NOM_MUNICIPIO")["ANIO"].value_counts()
av_e.groupby("NOM_MUNICIPIO").mean().sort_values(ascending=False)
Out[43]:
NOM_MUNICIPIO
Cuauhtémoc                1772.3
Iztapalapa                1764.7
Gustavo A. Madero         1713.0
Miguel Hidalgo            1231.9
Benito Juárez             1131.8
Coyoacán                  1115.3
Venustiano Carranza       1010.2
Álvaro Obregón             913.4
Tlalpan                    853.2
Azcapotzalco               605.0
Iztacalco                  566.0
Xochimilco                 301.4
Cuajimalpa de Morelos      242.2
Tláhuac                    199.1
La Magdalena Contreras     179.6
Milpa Alta                  82.1
Name: ANIO, dtype: float64

Como podemos ver el Promedio de accidentes de las delegaciones Cuauhtémoc,Iztapalapa y Gustavo A. Madero son las que tienen mayores promedios

¿Cuales son las tres delegaciones con mas accidentes y como es su tendencia?

Como lo hemos visto en las secciones previas, las delegaciones Cuauhtémoc,Iztapalapa y Gustavo A. Madero son las que registran mas accidentes. Ahora nos gustaria saber como es su tendencia a lo largo del periodo 2010 al 2019. Primero empezaremos ultizando el dataset creado en las secciones anteriores

In [44]:
delagacion_accidentes=delagacion_accidentes.loc[["Cuauhtémoc","Iztapalapa","Gustavo A. Madero"]]
In [45]:
delagacion_accidentes=delagacion_accidentes.reset_index(name="Num_Acc")
delagacion_accidentes
Out[45]:
NOM_MUNICIPIO ANIO Num_Acc
0 Cuauhtémoc 2010 1701
1 Cuauhtémoc 2011 1669
2 Cuauhtémoc 2012 2283
3 Cuauhtémoc 2013 2025
4 Cuauhtémoc 2014 1820
5 Cuauhtémoc 2015 1652
6 Cuauhtémoc 2016 1740
7 Cuauhtémoc 2017 1719
8 Cuauhtémoc 2018 1590
9 Cuauhtémoc 2019 1524
10 Iztapalapa 2010 1952
11 Iztapalapa 2011 1999
12 Iztapalapa 2012 2037
13 Iztapalapa 2013 2206
14 Iztapalapa 2014 2113
15 Iztapalapa 2015 1659
16 Iztapalapa 2016 1583
17 Iztapalapa 2017 1596
18 Iztapalapa 2018 1295
19 Iztapalapa 2019 1207
20 Gustavo A. Madero 2010 1883
21 Gustavo A. Madero 2011 2177
22 Gustavo A. Madero 2012 2022
23 Gustavo A. Madero 2013 1852
24 Gustavo A. Madero 2014 1647
25 Gustavo A. Madero 2015 1592
26 Gustavo A. Madero 2016 1478
27 Gustavo A. Madero 2017 1567
28 Gustavo A. Madero 2018 1505
29 Gustavo A. Madero 2019 1407

De manera grafica podriamos observar los resultados obtenidos y con el fin de facilitar la visualización de las tendencias se realizo un gráfico referente a ellos.

In [46]:
plt.style.use('ggplot')
fig = plt.figure(figsize=(10, 10))
sns.set(font_scale=1.2)
ax = sns.barplot(data=delagacion_accidentes, x="ANIO", y="Num_Acc", hue="NOM_MUNICIPIO")
ax.set_title('Delegaciones con mas accidentes', fontsize=20, pad=15)
ax.set(xlabel='Año', ylabel='Numero de Accidentes')
new_title = 'My title'
plt.legend(title='Delgacion');
In [47]:
(ggplot(delagacion_accidentes, aes(x="factor(ANIO)",y="Num_Acc", group = 1))
 +geom_point()+geom_smooth(method='lm',span=.2, se=False)+facet_wrap("NOM_MUNICIPIO",ncol=1)
 +ylab("Numero de Accidentes") +  xlab("Año")
)
Out[47]:
<ggplot: (-9223371848130693204)>

Como podemos observar las tendencias para las tres delegaciones es a la baja, por lo cual podriamos suponer que los accidentes en estas 3 delegaciones disminuiran en los proximos años. Durante los años 2012, y 2013 podemos observar que alcanzaron valores cercanos a los 2000 accidentes y en el 2019 únicamente la delegación Cuauhtémoc supero los 1500 accidentes.

¿En que año se han registrado mas accidentes en la CDMX y cual es su tendencia?

In [48]:
años_accidentes=df_cdmx.groupby("ANIO").size()
años_accidentes.sort_values(ascending=False)
Out[48]:
ANIO
2012    17120
2011    16466
2013    15742
2010    14729
2014    14319
2015    12337
2017    12321
2018    11656
2016    11449
2019    10673
dtype: int64

Como podemos observar el año en el cual se registraron mas accidentes fue el 2012, sin embargo seria interesante ver las tendencias que tienen los accidentes, para esto haremos la siguiente grafica

In [49]:
años_accidentes=años_accidentes.reset_index(name="Num_Acc")
años_accidentes
Out[49]:
ANIO Num_Acc
0 2010 14729
1 2011 16466
2 2012 17120
3 2013 15742
4 2014 14319
5 2015 12337
6 2016 11449
7 2017 12321
8 2018 11656
9 2019 10673
In [50]:
años_accidentes.corr(method="pearson")
Out[50]:
ANIO Num_Acc
ANIO 1.000000 -0.874329
Num_Acc -0.874329 1.000000

Para este caso específico se decidió analizar con el coeficiente de Pearson la relación entres los años y el número de accidentes registrados. Este podría ser un análisis preeliminar sobre la tendencia en el número de choques por año; de acuerdo al valor obtenido -0.87 podemos decir de primera instancia que a medida que aumenten los años, la cantidad de accidentes irán a la baja, sin embargo sería muy arriesgado sacar conclusiones a partir de este único indicador, por lo que en análisis posteriores, se complementará con el cooeficiente de spearman, la ecuación del gráfico y/o análisis más robustos como series de tiempos.

In [51]:
#plt.style.use('seaborn')
#fig = plt.figure(figsize=(5, 5))
#ax = fig.add_subplot()

#fig, ax = plt.subplots()
#ax2 = ax.twinx()
#ax.barplot(data=años_accidentes, x="ANIO", y="Num_Acc")
#ax2.regplot(x='ANIO', y='Num_Acc', data=años_accidentes, ax=axs[0])

#plt1=ax.barplot(data=años_accidentes, x="ANIO", y="Num_Acc");


#plt1 = ax.bar(value_counts.index, value_counts['M'], label='M',
#              color=["#7788AA","#4E638E","#2E4372","#152A55"])
#plt2 = ax.bar(value_counts.index, value_counts['F'], bottom=value_counts['M'],
 #             color=["#FFD0AA", "#D4996A", "#AA6B39", "#804415"])

#ax.set_ylabel('count')
#ax.set_title('Conteo de frecuencia de 4 deportes Olímpicos', fontsize=13, pad=15);
#plt.legend((plt1[0], plt2[0]), ('Men', 'Women'));
#ax.set_ylim(0, 4500);
#sns.barplot(data=años_accidentes, x="ANIO", y="Num_Acc");
#sns.regplot(x='ANIO', y='Num_Acc', data=años_accidentes, ax=ax)
#sns.lineplot(x="ANIO", y="Num_Acc", data=años_accidentes);
In [52]:
(
  ggplot(años_accidentes) + 
  aes(x="factor(ANIO)",y="Num_Acc", group = 1) + geom_col(alpha= 0.2, fill = "blue")+
  ggtitle("Histograma de Accidentes en la CDMX") +geom_point()+geom_smooth(method='lm',span=.2)+
  ylab("Accidentes totales") +
  xlab("Años")
)
Out[52]:
<ggplot: (-9223371848133492641)>

Similar a lo observado en la tendecia de las gráficas de las delegaciones con mayor cantidad de accidentes registrados y en concordancia con la relación del coeficiente de Pearson, se observa en los datos que la tendencia de los accidentes en la CDMX tiene una tendencia a disminuir, esto se debera validar posteriormente con modelos de predicción en futuros análisis

¿Quiénes son mas propensos a sufrir accidentes, los hombres o las mujeres y como es la tendencia?

Seria interesante analizar quienes son mas propensos a sufrir accidentes, para esto empezaremos analizando la cantidad de accidentes dependiendo del sexo.

In [53]:
df_cdmx.groupby('SEXO').size()#.map(lambda x:x*100/df_cdmx["ID_EDAD"].count()).loc[[0,99]]
Out[53]:
SEXO
Hombre     103402
Mujer       14420
Se fugó     18990
dtype: int64

A simple vista se puede observar que la mayoria de accidentes son causados por hombre. De igual forma, existe una gran cantidad de accidentes en los cuales el conducto se da a la fuga, Incluso superando los registros de mujeres involucradas en accidentes. Podriamos calcular el porcentaje de cada una de estas categorias para poder analizar mejor los datos.

In [54]:
df_cdmx.groupby('SEXO').size().apply(lambda x:x*100/df_cdmx["SEXO"].count())
Out[54]:
SEXO
Hombre     75.579628
Mujer      10.540011
Se fugó    13.880361
dtype: float64

Tal como lo habias observado el porcentaje de Mujeres involucradas en un accidente es mucho menor al de hombres, al igual que el de conductores que se dieron a la fuga. El siguiente paso es analizar las tendencias de accidentes tanto para hombres como mujeres, para saber si van a la baja o la alta.

In [55]:
filtro_sexo_accidentes=df_cdmx.groupby("SEXO")["ANIO"].value_counts().loc[["Hombre","Mujer"]]
filtro_sexo_accidentes=filtro_sexo_accidentes.reset_index(name="Num_Acc")
In [56]:
filtro_sexo_accidentes
Out[56]:
SEXO ANIO Num_Acc
0 Hombre 2012 13158
1 Hombre 2011 12228
2 Hombre 2013 11776
3 Hombre 2010 11518
4 Hombre 2014 10691
5 Hombre 2015 9546
6 Hombre 2017 9375
7 Hombre 2016 8829
8 Hombre 2018 8546
9 Hombre 2019 7735
10 Mujer 2013 1782
11 Mujer 2015 1602
12 Mujer 2014 1572
13 Mujer 2012 1535
14 Mujer 2011 1528
15 Mujer 2017 1465
16 Mujer 2018 1385
17 Mujer 2016 1340
18 Mujer 2019 1298
19 Mujer 2010 913
In [57]:
(ggplot(filtro_sexo_accidentes, aes(x="factor(ANIO)",y="Num_Acc",group = 1))
 +geom_col(alpha = 0.3)+facet_grid('SEXO ~ .',scales="free")+geom_point()+geom_smooth(span=.2,se=False)
 +ylab("Numero de Accidentes") +  xlab("Año")
)
Out[57]:
<ggplot: (-9223371848130694298)>

Adicionalmente podemos analizar el caso de las personas que se fugaron y su tendencia.

In [58]:
filtro_fuga_accidentes=df_cdmx.groupby("SEXO")["ANIO"].value_counts().loc["Se fugó"]
filtro_fuga_accidentes=filtro_fuga_accidentes.reset_index(name="Num_Acc")
In [59]:
(
  ggplot(filtro_fuga_accidentes) + 
  aes(x="factor(ANIO)",y="Num_Acc", group = 1) + geom_col(alpha= 0.2, fill = "blue")+
  ggtitle("Tedencia de la fuga de personas en accidentes en la CDMX") +geom_point()+geom_smooth(method='lm',span=.2)+
  ylab("Accidentes totales") +
  xlab("Años")
)
Out[59]:
<ggplot: (-9223371848133352921)>

De acuerdo a los graficos podemos observar una tendencia clara de disminucion de accidentes en el caso de hombres. En el caso de las mujeres la tendencia no es tan clara ya que hubo un aumento considerable de accidentes en el 2013, y en años posteriores la tendencia fue ligeramente a la baja. Por lo anterior podriamos suponer unas tendencias a la baja de los dos sexos en cuanto a los accidentes.

En cuanto a la tendencia de las personas a fugarse de los accidentes, los datos indican en general una tendencia de dismonucion. Sin embargo en los ultimos años el numero de personas que se fugan de los accidentes ha comnezado a aumentar ligeramente. Pero en general podriamos suponer que va a la baja.

¿Cuáles son los meses con mayores accidentes a los largo de los años?

Se realizó un análisis respecto a los meses con mayor número de accidentes a lo largo de los 10 años observados.

Para empezar de agruparon los datos del dataframe original por año y mes, posteriomente se concatenaron en un nuevo dataframe con únicamente los máximos de accidentes de todos los años, y se modificaron los meses para una mayor comprensión de los datos.

In [60]:
df_anios = df_cdmx.groupby(['ANIO','MES']).size()
print(df_anios)
df_maximos_anios = pd.DataFrame()
for anio in range(df_cdmx['ANIO'].unique().max(),df_cdmx['ANIO'].unique().min()-1,-1):
    df_maximos_anios = pd.concat([df_maximos_anios,df_anios[anio][df_anios[anio] == df_anios[anio].max()]])

df_maximos_anios['MES'] = df_maximos_anios.index

int_a_mes = {1 :'Enero',2 :'Febrero',3 : 'Marzo',4 : 'Abril', 5 : 'Mayo', 6 : 'Junio',
            7 : 'Julio', 8 : 'Agosto', 9 : 'Septiembre',10 : 'Octubre', 11 : 'Noviembre', 12 : 'Diciembre'}
df_maximos_anios['MES'] = df_maximos_anios['MES'].map(int_a_mes)
ANIO  MES
2010  1      1039
      2      1034
      3      1246
      4      1093
      5      1249
             ... 
2019  8       943
      9       953
      10     1027
      11      939
      12      915
Length: 120, dtype: int64
In [61]:
df_maximos_anios.set_index(df_cdmx['ANIO'].unique(),inplace=True)
df_maximos_anios.rename(columns={0 : 'Max_acci'},inplace=True)
df_maximos_anios.index.name = 'ANIO'

df_maximos_anios
Out[61]:
Max_acci MES
ANIO
2019 1027.0 Octubre
2018 1160.0 Agosto
2017 1249.0 Agosto
2016 1089.0 Septiembre
2015 1135.0 Junio
2014 1311.0 Octubre
2013 1426.0 Octubre
2012 1510.0 Octubre
2011 1679.0 Octubre
2010 1414.0 Octubre

En el código aqui presente se obtuvieron los meses con mayor número de accidentes en los 10 años y se observó que el mes con más accidentes fue Obtubre en 6 años del total observado, seguido por Agosto, Septiembre y Junio respectivamente.

In [62]:
df_maximos_anios.groupby('MES').size().sort_values(ascending=False)
Out[62]:
MES
Octubre       6
Agosto        2
Septiembre    1
Junio         1
dtype: int64
In [63]:
df_gra=df_cdmx.groupby(["ANIO","MES"]).size()#["FECHA_DIA"].value_counts()
df_gra=df_gra.reset_index()
df_gra.columns =["Año","Mes","count"]
In [64]:
plt.style.use('seaborn')
sns.set(font_scale=1.5)
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot()
sns.barplot(x="Mes",y="count", ax=ax, palette='Paired',hue="Año",data=df_gra);
ax.set_ylabel('Numero de Accindentes')
ax.set_title('Histograma de Accidentes por mes y año')
labels=["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"]
ax.set_xticklabels(labels)
plt.legend(title="Año",bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.);
#ax = sns.barplot(x="day", y="total_bill", hue="sex", data=tips)

Se grafican los datos de los accidentes contra los meses segun los años observados para comprobar los resultados arrojados en el proceso anterior.

¿Cuáles son los dias de la semana con mayores accidentes a los largo de los años?

Se realizó un analisis respecto a los dias con mayor número de accidentes a lo largo de los 10 años observados.

In [65]:
df_cdmx["FECHA_DIA"]=df_cdmx["FECHA"].dt.weekday
In [66]:
#df_cdmx.groupby("FECHA_DIA").size()
df_gra=df_cdmx.groupby(["FECHA_DIA","ID_HORA"]).size()#["FECHA_DIA"].value_counts()
df_gra=df_gra.reset_index()
df_gra.columns =["Dia","Hora","count"]
df_gra
Out[66]:
Dia Hora count
0 0 0 502
1 0 1 370
2 0 2 341
3 0 3 263
4 0 4 280
... ... ... ...
163 6 19 716
164 6 20 773
165 6 21 859
166 6 22 738
167 6 23 649

168 rows × 3 columns

In [67]:
plt.style.use('ggplot')
g = sns.FacetGrid(data = df_gra, col = 'Dia', col_wrap = 3)
g.map(plt.bar, 'Hora','count')#.set(yscale = 'log')
g.set_xlabels('Hora del Dia')
g.set_ylabels('Numero de Accidentes')
days=["Lunes","Martes","miercoles","Jueves","Viernes","sabado","domingo"]
#ax.set(xlabel='Año', ylabel='Numero de Accidentes');

for ax in g.axes.flatten():
    ax.tick_params(labelbottom=True)
    #ax.set(xlabel='Hora del Dia')
axes = g.axes.flatten()
[axes[x].set_title(days[x]) for x in range(7)];

En esta gráfica observamos la cantidad de accidentes a lo largo del día y evaluado por día de la semana. El Lunes es nuestro día 0 y el Domingo el día 6. Podemos observar que la cantidad de accidentes se comporta de manera ascendente conforme transcurre el día con excepción de horas del día específicos como 9 de la mañana. El Viernes podemos ver valores más altos y mantenidos, sin embargo Míercoles y Jueves destacan por tener los valores más altos registrados.

Con los resultados de las gráficas anteriores se procedió a agrupar los datos del dataframe original por año y dia, posteriomente se concatenaron en un nuevo dataframe con únicamente los máximos de accidentes de todos los años.

In [68]:
df_anios_dias = df_cdmx.groupby(['ANIO','DIASEMANA']).size()
In [69]:
df_maximos_anios_dias = pd.DataFrame()
for anio in range(df_cdmx['ANIO'].unique().max(),df_cdmx['ANIO'].unique().min()-1,-1):
    df_maximos_anios_dias = pd.concat([df_maximos_anios_dias,df_anios_dias[anio][df_anios_dias[anio] == df_anios_dias[anio].max()]])
In [70]:
df_maximos_anios_dias
Out[70]:
0
Viernes 1612.0
Viernes 1807.0
Viernes 1909.0
Viernes 1740.0
Jueves 1939.0
Viernes 2292.0
Viernes 2571.0
Viernes 2620.0
Viernes 2523.0
Viernes 2265.0

A primera vista, se observa que a lo largo de los años observados el dia viernes destaca como el dia donde hay mayores accidentes en cada una de las observaciones.

In [71]:
df_maximos_anios_dias['DIAS'] = df_maximos_anios_dias.index
df_maximos_anios_dias.set_index(df_cdmx['ANIO'].unique(),inplace=True)
df_maximos_anios_dias.rename(columns={0 : 'Max_acci'},inplace=True)
df_maximos_anios_dias.index.name = 'ANIO'

df_maximos_anios_dias
Out[71]:
Max_acci DIAS
ANIO
2019 1612.0 Viernes
2018 1807.0 Viernes
2017 1909.0 Viernes
2016 1740.0 Viernes
2015 1939.0 Jueves
2014 2292.0 Viernes
2013 2571.0 Viernes
2012 2620.0 Viernes
2011 2523.0 Viernes
2010 2265.0 Viernes

Una vez con los datos acomodados correctamente se procedió a obtener la cantidad de años en donde cada día tuvo el máximo de accidentes, siendo el dia viernes con mayor número de accidentes ya que en 9 años del total observado este dia destaca con mayores accidentes, seguido por el dia jueves.

In [72]:
df_maximos_anios_dias.groupby('DIAS').size().sort_values(ascending=False)
Out[72]:
DIAS
Viernes    9
Jueves     1
dtype: int64

¿Cual es la edad mas propensa a sufrir accidentes?

Para responder esta pregunta, primero tenemos que contabilizar el numero de accidentes en base a la edad, del año 2010 al 2019, depues ordenaremos los datos de manera descendiente para poder analizar las edades con mas accidentes

In [73]:
df_cdmx.groupby("ID_EDAD")["ID_EDAD"].count().sort_values(ascending=False)
Out[73]:
ID_EDAD
99    26480
0     18990
30     3693
40     3340
28     3000
      ...  
89        3
13        3
95        2
91        1
94        1
Name: ID_EDAD, Length: 83, dtype: int64

De manera grafica podemos verlo de la siguiente manera

In [74]:
fig = plt.figure(figsize=(12, 8))
sns.set(font_scale=1.5)
ax=sns.distplot(df_cdmx['ID_EDAD'], kde=False, norm_hist=False, bins=100)
ax.set_title('Histograma de Accidentes en la CDMX', fontsize=20, pad=15)
ax.set(xlabel='Edad', ylabel='Numero de Accidentes');

Como podemos observar existe una gran cantidad de datos pertenecientes a la edad de 0 y 99 lo cual no hace sentido, esta gráfica es como se observan los datos sin ninguna manipulación, sin embargo se asume que son datos que no lograron recabarse de manera correcta por lo cuál se decidio abordar la situación de la manera mostrada abajo.

¿Que porcentaje de datos de edades de 99 y 100 años hay en los datos?

Apartir de la utima grafica obtenida de numero de accidentes en funcion de la edad se comienza a analizar los datos. Primero se observa que los valores de edad 0 y 99 albergan demasiados datos, de acuerdo a los registros del INEGI cuando el conductor se fugaba, los registros asignan el valor 0 a la edad. En cuanto a 99 significa que se desconoce la edad del conductor.

In [75]:
df_cdmx.groupby('ID_EDAD').size().map(lambda x:x*100/df_cdmx["ID_EDAD"].count()).loc[[0,99]]
Out[75]:
ID_EDAD
0     13.880361
99    19.355027
dtype: float64

Como podemos notar el porcentaje de datos pertenecientes a estas dos categorias es arriba del 30% de los datos por lo cual no es muy recomendable eliminar todas las filas pertenecientes a estos datos para futuras predicciones o algoritmos de prediccion. Sin embargo, podriamos analizar un poco los datos de edades excluyedo estas dos categorias

In [76]:
filtro_no_cero=df_cdmx["ID_EDAD"]!=0
filtro_no_noventa=df_cdmx["ID_EDAD"]!=99
In [77]:
df_cdmx_filtrado=df_cdmx[filtro_no_cero & filtro_no_noventa]
df_cdmx_filtrado.head()
Out[77]:
COBERTURA ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA DIASEMANA URBANA ... PEATHERIDO CICLMUERTO CICLHERIDO OTROMUERTO OTROHERIDO CLASACC ESTATUS NOM_MUNICIPIO FECHA FECHA_DIA
0 Municipal 9 2 2019 1 19 59 1 Martes Accidente en intersección ... 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-01 19:59:00 1
3 Municipal 9 2 2019 1 15 55 5 Sabado Accidente en intersección ... 0 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-05 15:55:00 5
4 Municipal 9 2 2019 1 14 30 9 Miercoles Accidente en intersección ... 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-09 14:30:00 2
6 Municipal 9 2 2019 1 9 0 11 Viernes Accidente en intersección ... 0 0 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-11 09:00:00 4
8 Municipal 9 2 2019 1 16 3 11 Viernes Accidente en intersección ... 1 0 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-11 16:03:00 4

5 rows × 46 columns

In [78]:
fig = plt.figure(figsize=(12, 8))
sns.set(font_scale=1.5)
ax=sns.distplot(df_cdmx_filtrado['ID_EDAD'], kde=False, norm_hist=False, bins=90)
ax.set_title('Histograma de Accidentes en la CDMX', fontsize=20, pad=15)
ax.set(xlabel='Edad', ylabel='Numero de Accidentes');

Filtrando los datos, podemos observar un mejor comportamiento en la grafica, de igual forma podemos determinar la edad que ha sufrido mas accidentes (moda) y el promedio de edad

In [79]:
#df_cdmx_filtrado.groupby("ID_EDAD")["ID_EDAD"].count().loc[]
#Promedio de edad
df_cdmx_filtrado["ID_EDAD"].mean()
Out[79]:
37.4163254581682
In [80]:
#Edad con mas Accidentes
df_cdmx_filtrado["ID_EDAD"].mode()
Out[80]:
0    30
dtype: int64
In [81]:
#top 5 edades
df_cdmx_filtrado.groupby("ID_EDAD")["ID_EDAD"].count().sort_values(ascending=False).head(5)
Out[81]:
ID_EDAD
30    3693
40    3340
28    3000
32    2998
29    2989
Name: ID_EDAD, dtype: int64

De acuerdo a los registros 30 años es la edad que tiene mas accidentes acumulados del 2010 al 2019, de igual forma podemos ver el top 5 de edades con mas accidentes acumulados siendo todas edades arriba de los 27 años.

De nuevo y en un posible anaálsis futuro sería recomendable evaluar la cantidad de accidentes por edad y la cantidad de población de esa edad que transita. Esto con el fin de eliminar sesgos, similar a lo que ocurre en el sexo.

¿Cual es la Tedencia de las edades mas propensas a sufrir accidentes del 2010 al 2019?

Para esto analizaremos las 3 edades con mas registros de accidentes y veremos como han variado a lo largo de los años

  • Para la edad de 30
In [82]:
Tendencia_años=df_cdmx_filtrado.groupby('ID_EDAD')['ANIO'].value_counts()
In [83]:
Tendencia_30_años=Tendencia_años.loc[30].sort_index(ascending=True)
Tendencia_30_años
Out[83]:
ANIO
2010    270
2011    268
2012    240
2013    503
2014    453
2015    395
2016    401
2017    422
2018    349
2019    392
Name: ANIO, dtype: int64
In [84]:
Tendencia_30_años.plot(xlabel='Año', ylabel='Numero de Accidentes');
Out[84]:
<AxesSubplot:xlabel='Año', ylabel='Numero de Accidentes'>
In [85]:
T_30=Tendencia_30_años.to_frame()#.reset_index(level='ANIO',col_level=1, col_fill='genus')
T_30.columns = ['NUM_ACC']
T_30.reset_index(inplace=True)
T_30.corr(method="pearson")
Out[85]:
ANIO NUM_ACC
ANIO 1.00000 0.46989
NUM_ACC 0.46989 1.00000

Como se puede obsevar en la gráfica el comportamiento es un poco irregular. Definitavamente requerirá se lleve a cabo un análisis mucho más completo. Nuestro análisis preeliminar utilizando coeficiente de Pearson, tampoco nos permite ver alguna relación directa o indirecta significativa. Un ajuste polinomial de grado 5 probablemente podrá ajustarse a esta gráfica, aunque sería bueno poder realizar algun estudio con serie de tiempo para obtener resultados mas precisos.

  • Para la edad de 40
In [86]:
Tendencia_40_años=Tendencia_años.loc[40].sort_index(ascending=True)
Tendencia_40_años
Out[86]:
ANIO
2010    267
2011    264
2012    225
2013    492
2014    454
2015    356
2016    337
2017    349
2018    330
2019    266
Name: ANIO, dtype: int64
In [87]:
Tendencia_40_años.plot(xlabel='Año', ylabel='Numero de Accidentes');
Out[87]:
<AxesSubplot:xlabel='Año', ylabel='Numero de Accidentes'>

Observamos en esta gráfica, que la tendencia de este grupo de edad va a la baja de acuerdo a los datos obtenidos en el 2019, al igual que los grupos de años anteriores en el 2013 fue cuando se obtuvo el valor máximo registrado de número de accidentes. Sin emabrgo, el coeficiente de Pearson es positivo pero al ser tan cercano a cero indica una correlación casi nula que es lógica, dado que pese a que son pocos datos hay mucha variación entre los años.

In [88]:
T_40=Tendencia_40_años.to_frame()#.reset_index(level='ANIO',col_level=1, col_fill='genus')
T_40.columns = ['NUM_ACC']
T_40.reset_index(inplace=True)
T_40.corr(method="pearson")
Out[88]:
ANIO NUM_ACC
ANIO 1.000000 0.109287
NUM_ACC 0.109287 1.000000
  • Para la edad de 28 años
In [89]:
Tendencia_28_años=Tendencia_años.loc[28].sort_index(ascending=True)
Tendencia_28_años
Out[89]:
ANIO
2010    179
2011    140
2012    196
2013    483
2014    407
2015    330
2016    312
2017    353
2018    305
2019    295
Name: ANIO, dtype: int64
In [90]:
Tendencia_28_años.plot(xlabel='Año', ylabel='Numero de Accidentes');
Out[90]:
<AxesSubplot:xlabel='Año', ylabel='Numero de Accidentes'>
In [91]:
T_28=Tendencia_28_años.to_frame()#.reset_index(level='ANIO',col_level=1, col_fill='genus')
T_28.columns = ['NUM_ACC']
T_28.reset_index(inplace=True)
T_28.corr(method="pearson")
Out[91]:
ANIO NUM_ACC
ANIO 1.000000 0.416955
NUM_ACC 0.416955 1.000000

Observamos un comportamiento similar a las anteriores en los primeros años de la gráfica, con una tendencia a la baja en el último año, pero un 2017 en compración con los registros de los demás años, de nuevo es difícil genera una interpretación o predicción con el gráfico y el coeficiente de Pearson, definitavamente el análisis inferencial será de gran utilidad para poder dar una predicción más certera del comportamiento de este tipo de siniestro en los años venideros.

En base a los resultados obtenidos podemos obervar que para las edades de 40 y 28 años las tendencias parecen ir a la baja lo que nos podria indicar una reduccion en los accidentes a esta edad. En cambio para la edad con mas registros de accidentes que es 30 años, la tendencia parece indicar que seguira siendo la edad con mas accidentes.

¿Que vehiculo es el que causa mas accidentes?

Como se observo cuando se estaba analizando el Dataset, cada tipo de vehiculo tiene su propia columna por lo cual es necesario tranformar estas columnas en filas para poder realizar algunas agregaciones y calculos. Para realizar esto, primero necesitamos elegir mas columnas que queremos trasnformar, las cuales se almacenaran en modelo_columnas.

In [92]:
modelo_columnas=["AUTOMOVIL","CAMPASAJ","MICROBUS","PASCAMION","OMNIBUS","TRANVIA",
                 "CAMIONETA","CAMION","TRACTOR","FERROCARRI","MOTOCICLET","BICICLETA","OTROVEHIC"]
columnas_filtradas=[i for i in list(df_cdmx.columns) if i not in modelo_columnas]
In [93]:
df_tipo_vehiculo=df_cdmx.melt(id_vars=columnas_filtradas,var_name ='TIPO_VEHICULO', value_name ='NUM_ACC')
df_tipo_vehiculo.head()
Out[93]:
COBERTURA ID_ENTIDAD ID_MUNICIPIO ANIO MES ID_HORA ID_MINUTO ID_DIA DIASEMANA URBANA ... CICLHERIDO OTROMUERTO OTROHERIDO CLASACC ESTATUS NOM_MUNICIPIO FECHA FECHA_DIA TIPO_VEHICULO NUM_ACC
0 Municipal 9 2 2019 1 19 59 1 Martes Accidente en intersección ... 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-01 19:59:00 1 AUTOMOVIL 1
1 Municipal 9 2 2019 1 3 37 5 Sabado Accidente en intersección ... 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-05 03:37:00 5 AUTOMOVIL 2
2 Municipal 9 2 2019 1 14 23 5 Sabado Accidente en intersección ... 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-05 14:23:00 5 AUTOMOVIL 1
3 Municipal 9 2 2019 1 15 55 5 Sabado Accidente en intersección ... 0 0 0 No fatal Cifras Definitivas Azcapotzalco 2019-01-05 15:55:00 5 AUTOMOVIL 1
4 Municipal 9 2 2019 1 14 30 9 Miercoles Accidente en intersección ... 0 0 0 Sólo daños Cifras Definitivas Azcapotzalco 2019-01-09 14:30:00 2 AUTOMOVIL 2

5 rows × 35 columns

In [94]:
df_vehiculo_agg=df_tipo_vehiculo.groupby(["ANIO","TIPO_VEHICULO"])["NUM_ACC"].sum()
df_vehiculo_agg
Out[94]:
ANIO  TIPO_VEHICULO
2010  AUTOMOVIL        22648
      BICICLETA          152
      CAMION             356
      CAMIONETA         1215
      CAMPASAJ           883
                       ...  
2019  OMNIBUS             12
      OTROVEHIC           55
      PASCAMION          751
      TRACTOR            181
      TRANVIA             29
Name: NUM_ACC, Length: 130, dtype: int64

Arreglando la serie para convertirla en un data frame, podemos graficarlo para poder visulaizar los resultados

In [95]:
df_vehiculo_agg=df_vehiculo_agg.to_frame().reset_index()
df_vehiculo_agg
Out[95]:
ANIO TIPO_VEHICULO NUM_ACC
0 2010 AUTOMOVIL 22648
1 2010 BICICLETA 152
2 2010 CAMION 356
3 2010 CAMIONETA 1215
4 2010 CAMPASAJ 883
... ... ... ...
125 2019 OMNIBUS 12
126 2019 OTROVEHIC 55
127 2019 PASCAMION 751
128 2019 TRACTOR 181
129 2019 TRANVIA 29

130 rows × 3 columns

In [96]:
plt.style.use('ggplot')
sns.set(font_scale=1.2)
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot()
sns.barplot(x="NUM_ACC",y="TIPO_VEHICULO", ax=ax, palette='viridis',hue="ANIO",data=df_vehiculo_agg);
ax.set_ylabel('Tipo de vehiculo')
ax.set_xlabel('Numero de Accidentes')
ax.set_title('Histograma de Accidentes por tipo de vehiculo')
plt.legend(title="Año",bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.);
#ax = sns.barplot(x="day", y="total_bill", hue="sex", data=tips)
In [97]:
!pip install plotly
Requirement already satisfied: plotly in c:\users\sergio\anaconda3\lib\site-packages (4.14.3)
Requirement already satisfied: six in c:\users\sergio\anaconda3\lib\site-packages (from plotly) (1.12.0)
Requirement already satisfied: retrying>=1.3.3 in c:\users\sergio\anaconda3\lib\site-packages (from plotly) (1.3.3)

Podemos visualizar los datos de una manera mejor utilizando Treemaps.

In [98]:
df_vehiculo_agg
df_vehiculo_agg["Tipo"]="Accidentes"
In [99]:
import plotly.express as px
fig = px.treemap(df_vehiculo_agg, path=["Tipo",'ANIO', 'TIPO_VEHICULO'], values='NUM_ACC')

fig.show()

En el grafico y analisis de datos podemos observar como, los accidentes de autos son los mas comunes. Lo cual es algo que ya esperabamos, ya que existen muchos mas automoviles en circulacion que los otros tipos de vehiculos.

In [100]:
df_vehiculo_agg.groupby("TIPO_VEHICULO")["NUM_ACC"].sum().sort_values(ascending=False)
Out[100]:
TIPO_VEHICULO
AUTOMOVIL     185484
CAMPASAJ       22476
MOTOCICLET      9885
PASCAMION       9229
CAMIONETA       8378
MICROBUS        6668
CAMION          4691
TRACTOR         2731
BICICLETA       1488
OTROVEHIC        720
TRANVIA          462
OMNIBUS          247
FERROCARRI         5
Name: NUM_ACC, dtype: int64

Tambien calculando el acumulado de los accidentes, podemos determinar los vehiculos que mas accidentes generaron en este caso el top 3 de tios de vehiculos que causaron mas accidentes son Automovil, Camioneta de pasajeros y Motocicletas

¿Cual es la tendencia de los 6 tipos de vehiculos que causan mas accidentes?

Una vez que tenemos claro los tipos de vehiculos que causan mas accidentes, seria interesante observar si existe una tendencia en los tipos de vehiculos con mas accidentes y si esta es al aumento o disminucion

Primero empezaremos filtrando los 3 tipos de vehiculos con mas accidentes los cuales son Automovil(AUTOMOVIL), Camioneta de pasajeros (CAMPASAJ) y Motocicletas (MOTOCICLET)

In [101]:
filtro_top=df_vehiculo_agg.query('TIPO_VEHICULO=="AUTOMOVIL" or TIPO_VEHICULO=="CAMPASAJ" or TIPO_VEHICULO=="MOTOCICLET"')
In [102]:
(ggplot(filtro_top, aes("factor(ANIO)","NUM_ACC",group=1))
 +geom_col(alpha= 0.2, fill = "blue")
 +geom_point()+geom_smooth(method='lm',span=.2)
 +facet_grid("TIPO_VEHICULO~ .",scales = 'free')
 +theme(axis_text_x = element_text(angle=45, hjust=1))+ ggtitle("Accidentes por tipo de vehiculo y año") +
  xlab("Año") +labs(fill = "YEAR")+ylab("Numero de accidentes")
)
Out[102]:
<ggplot: (-9223371848125403960)>

A diferencia de la tendencia del camión de pasajeros y de los automóviles que presentan ambos una tendecia a la baja, las motocicletas tienen una ligera tendencia a la alta, especialmente en el año 2019.

De nuevo será útil valorar y analizar estas tendencias con la cantidad de parque vehicular relativo de cada tipo de vehículo.

Para analizar los 3 vehiculos pertenecistes al top 6 se realizar lo siguiente:

In [103]:
filtro_top=df_vehiculo_agg.query('TIPO_VEHICULO=="PASCAMION" or TIPO_VEHICULO=="CAMIONETA" or TIPO_VEHICULO=="MICROBUS"')
In [104]:
(ggplot(filtro_top, aes("factor(ANIO)","NUM_ACC",group=1))
 +geom_col(alpha= 0.2, fill = "blue")
 +geom_point()+geom_smooth(method='lm',span=.2)
 +facet_grid("TIPO_VEHICULO~ .",scales = 'free')
 +theme(axis_text_x = element_text(angle=45, hjust=1))+ ggtitle("Accidentes por tipo de vehiculo y año") +
  xlab("Año") +labs(fill = "YEAR")+ylab("Numero de accidentes")
)
Out[104]:
<ggplot: (-9223371848125177284)>

A diferencia del caso anterior, las tres gráficas de los tipos de automóviles presentan una línea de tendencia que va a la baja, para el caso del Microbus es espcialmente marcada esta tendencia, por lo cual podriamos de igual manera analizar que factores pudieron influir para que esto sucediera.

Análsis de correlación con parque vehicular

In [105]:
url= "https://www.inegi.org.mx/contenidos/programas/vehiculosmotor/datosabiertos/vmrc_anual_csv.zip"
In [106]:
file = "vmrc_anual_csv.zip"

if not os.path.isfile(file):
    print("Descargando archivo")
    r = urllib.request.urlopen(url)
    f = open(file,"wb")
    f.write(r.read())
    f.close()
    print("Se ha descargado el archivo")
    
else: 
    print("Ya existe el archivo")
    
if not os.path.exists("vmrc_anual_csv"):
    os.mkdir("vmrc_anual_csv")
    zf = zipfile.ZipFile(file, "r")
    zf.extractall(path = "vmrc_anual_csv")
Descargando archivo
Se ha descargado el archivo
In [107]:
f=pd.read_csv("vmrc_anual_csv\conjunto_de_datos/vmrc_2019.csv",index_col=False)
In [108]:
filepaths = [f for f in listdir("vmrc_anual_csv\conjunto_de_datos") if f.endswith('.csv')]
In [109]:
lista_archivos=list(map(lambda x: "vmrc_anual_csv\conjunto_de_datos/"+x, sorted(filepaths,reverse=True)[:10]))
In [110]:
df = pd.concat(map(lambda archivo: pd.read_csv(archivo,index_col=False),lista_archivos))

Para la acotación correspondiente a nuestro proyecto, Filtramos los datos pertenecientes a la Ciudad de Mexico cuyo código de entidad es 9

In [111]:
df_cdmx_parque = df[(df.ID_ENTIDAD==9) & (df.ID_MUNICIPIO!=999)]
df_cdmx_parque = df_cdmx_parque.reset_index(drop=True)

Se realizó la suma de las columnas, con el objetivo de obtener todos los Autos, motos y camiones de pasajeros registrados en el parque vehicular.

In [112]:
df_cdmx_parque["AUTOSParque"] =  df_cdmx_parque[['AUTO_OFICIAL','AUTO_PUBLICO','AUTO_PARTICULAR']].sum(axis=1)
df_cdmx_parque["MOTOSParque"] = df_cdmx_parque[['MOTO_OFICIAL','MOTO_DE_ALQUILER','MOTO_PARTICULAR']].sum(axis=1)
df_cdmx_parque["CAMParque"] = df_cdmx_parque[['CAM_PAS_OFICIAL','CAM_PAS_PUBLICO','CAM_PAS_PARTICULAR']].sum(axis=1)
df_cdmx_parque.head()
Out[112]:
PROD_EST COBERTURA ANIO ID_ENTIDAD ID_MUNICIPIO AUTO_OFICIAL AUTO_PUBLICO AUTO_PARTICULAR CAM_PAS_OFICIAL CAM_PAS_PUBLICO ... CYC_CARGA_OFICIAL CYC_CARGA_PUBLICO CYC_CARGA_PARTICULAR MOTO_OFICIAL MOTO_DE_ALQUILER MOTO_PARTICULAR ESTATUS AUTOSParque MOTOSParque CAMParque
0 Vehículos de motor registrados en circulación.... Municipal 2019 9 2 0 7625 289334 0 0 ... 0 205 5259 0 0 20466 Cifras Definitivas. 296959 20466 1195
1 Vehículos de motor registrados en circulación.... Municipal 2019 9 3 0 11107 467093 0 0 ... 0 141 3718 0 0 35495 Cifras Definitivas. 478200 35495 2266
2 Vehículos de motor registrados en circulación.... Municipal 2019 9 4 0 1743 151283 0 0 ... 0 46 1361 0 0 10300 Cifras Definitivas. 153026 10300 778
3 Vehículos de motor registrados en circulación.... Municipal 2019 9 5 0 21700 541572 0 0 ... 0 221 5569 0 0 44159 Cifras Definitivas. 563272 44159 3960
4 Vehículos de motor registrados en circulación.... Municipal 2019 9 6 0 8768 233215 0 0 ... 0 151 3817 0 0 18539 Cifras Definitivas. 241983 18539 1646

5 rows × 21 columns

Se genero un nuevo dataframe para la posterior comparacion con los accidentes reportandos correspondientes a las categorias de autos, motos y camiones de pasajeros.

In [113]:
df_parque_vehicular = df_cdmx_parque[['ANIO','ID_MUNICIPIO','AUTOSParque','MOTOSParque','CAMParque']]
df_parque_vehicular.head(20)
Out[113]:
ANIO ID_MUNICIPIO AUTOSParque MOTOSParque CAMParque
0 2019 2 296959 20466 1195
1 2019 3 478200 35495 2266
2 2019 4 153026 10300 778
3 2019 5 563272 44159 3960
4 2019 6 241983 18539 1646
5 2019 7 731056 68737 9657
6 2019 8 127246 9949 1148
7 2019 9 53043 4464 449
8 2019 10 409430 40125 2647
9 2019 11 123170 19421 1317
10 2019 12 389891 28985 355
11 2019 13 167284 24468 1603
12 2019 14 492782 42710 427
13 2019 15 491346 49926 2249
14 2019 16 499510 32576 870
15 2019 17 274621 23256 1252
16 2018 2 287406 17299 1201
17 2018 3 461356 30830 2279
18 2018 4 146080 8779 779
19 2018 5 542134 36823 3971

Se realizó una agrupacion por años y municipios para posteriomente realizar una suma sobre las columnas del dataframe de accidentes para la posterior comparación.

In [114]:
df_accidentes = df_cdmx.groupby(["ANIO","ID_MUNICIPIO"])[['AUTOMOVIL', 'CAMPASAJ', 'MICROBUS', 'PASCAMION', 'OMNIBUS', 'TRANVIA',
       'CAMIONETA','MOTOCICLET']].sum().reset_index()

Fue necesario sumar las columnas 'CAMPASAJ', 'MICROBUS', 'PASCAMION', 'OMNIBUS', 'TRANVIA', 'CAMIONETA' para la correcta comparacion del parque vehicular de los camiones de pasajeros.

In [115]:
df_accidentes["CAMIONPAS"] = df_accidentes[['CAMPASAJ', 'MICROBUS', 'PASCAMION', 'OMNIBUS', 'TRANVIA',
       'CAMIONETA']].sum(axis = 1)
In [116]:
df_parque_accidentes = df_accidentes[['ANIO','ID_MUNICIPIO','AUTOMOVIL','MOTOCICLET','CAMIONPAS']]
df_parque_accidentes.head()
Out[116]:
ANIO ID_MUNICIPIO AUTOMOVIL MOTOCICLET CAMIONPAS
0 2010 2 901 39 228
1 2010 3 1900 68 322
2 2010 4 317 8 68
3 2010 5 2859 85 575
4 2010 6 1054 45 182
In [117]:
df_parque_accidentes = pd.merge(df_parque_accidentes,df_parque_vehicular)
In [118]:
df_parque_accidentes = df_parque_accidentes.rename(columns={'AUTOMOVIL': 'AUTOSAcci','MOTOCICLET':'MOTOSAcci','CAMIONPAS':'CAMAcci'})
In [119]:
df_parque_accidentes = pd.merge(df_parque_accidentes,delegacion_nombre[['ID_MUNICIPIO', 'NOM_MUNICIPIO']],how='left')
df_parque_accidentes.head()
Out[119]:
ANIO ID_MUNICIPIO AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque NOM_MUNICIPIO
0 2010 2 901 39 228 199509 0 994 Azcapotzalco
1 2010 3 1900 68 322 325723 0 1736 Coyoacán
2 2010 4 317 8 68 82325 0 536 Cuajimalpa de Morelos
3 2010 5 2859 85 575 339930 0 3165 Gustavo A. Madero
4 2010 6 1054 45 182 163662 0 1098 Iztacalco

Ya con el dataframe presente se comenzaron los análisis correspondientes.

Se empezo con el cálculo de estimados de locación y estadisticos de orden, obteniendo en la siguiente tabla el promedio, mediana, desviación estándar, min, max y cuartiles de los datos, con los datos sepaarados por alcaldia.

In [120]:
df_parque_accidentes[['AUTOSAcci','MOTOSAcci','CAMAcci','AUTOSParque','MOTOSParque','CAMParque']].describe()
Out[120]:
AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque
count 160.000000 160.000000 160.000000 160.000000 160.000000 160.000000
mean 1159.275000 61.781250 296.625000 276735.643750 13432.300000 1898.143750
std 829.376586 49.455993 199.142651 157130.958176 13804.314415 1913.314631
min 72.000000 0.000000 14.000000 17890.000000 0.000000 304.000000
25% 334.500000 21.000000 110.000000 130378.000000 2281.750000 861.000000
50% 1093.500000 52.000000 278.000000 266844.500000 9068.000000 1311.500000
75% 1760.000000 85.000000 436.500000 390242.000000 21102.000000 2147.000000
max 3162.000000 220.000000 858.000000 731056.000000 68737.000000 10467.000000

Viendo estos números podemos inferir varias cosas:

1 En la columna de Accidentes de autos una gran parte de nuestros datos estan en valores menores a 1760.
2 En la columna de Accidentes de motos una gran parte de nuestros datos estan en valores menores a 85.
3 En la columna de Accidentes de camiones una gran parte de nuestros datos estan en valores menores a 436.
4 Se puede observar que los accidentes de todas las columnas la mayoria de los datos se concentran abajo de nuesto 75%.
5 En la parte del parque vehicular exiten valores muy grandes al llegar a nuestro maximo, ya que hay alcandias con una gran cantidad de vehiculos

En esta parte se agruparon los datos por año y de obtuvieron los mismos calculos del análisis anterior.

In [121]:
df_parque_accidentes.groupby('ANIO')[['AUTOSAcci','MOTOSAcci','CAMAcci','AUTOSParque','MOTOSParque','CAMParque']].sum().describe()
Out[121]:
AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque
count 10.000000 10.000000 10.000000 1.000000e+01 10.000000 10.000000
mean 18548.400000 988.500000 4746.000000 4.427770e+06 214916.800000 30370.300000
std 3802.640258 102.470863 965.442673 7.398026e+05 170846.940747 3286.291765
min 14106.000000 789.000000 3395.000000 3.348416e+06 0.000000 24051.000000
25% 15528.500000 921.750000 4102.500000 3.823131e+06 67139.500000 31081.750000
50% 17389.500000 1005.500000 4584.500000 4.524334e+06 235059.500000 31580.500000
75% 22338.750000 1058.250000 5652.750000 4.958066e+06 336035.000000 32159.000000
max 23704.000000 1144.000000 5951.000000 5.492819e+06 473576.000000 33189.000000

Tras estos cálculos se observa que la distribucion de los accidentes y parque vehicular por años esta mejor distribuido.

Se ralización distintas gráficas para observar si esque exitia relacion entre los accidentes de cada categoría y el parque vehicular.

Gráficas scatter para comparar las columnas

In [122]:
ax = sns.scatterplot(df_parque_accidentes['AUTOSParque'],df_parque_accidentes['AUTOSAcci']);
ax.set(xlabel = 'Parque vehicular Automoviles', ylabel = 'Número de accidentes')
ax.set_title('Gráfica análisis de Automovil Parque vs Accidentes')
Out[122]:
Text(0.5, 1.0, 'Gráfica análisis de Automovil Parque vs Accidentes')
In [123]:
ax = sns.scatterplot(df_parque_accidentes['MOTOSParque'],df_parque_accidentes['MOTOSAcci']);
ax.set(xlabel = 'Parque vehicular Motocicletas', ylabel = 'Número de accidentes')
ax.set_title('Gráfica análisis de Motocicleta Parque vs Accidentes')
Out[123]:
Text(0.5, 1.0, 'Gráfica análisis de Motocicleta Parque vs Accidentes')
In [124]:
ax = sns.scatterplot(df_parque_accidentes['CAMParque'],df_parque_accidentes['CAMAcci']);
ax.set(xlabel = 'Parque vehicular Camiones pasajeros', ylabel = 'Número de accidentes')
ax.set_title('Gráfica análisis de Camiones pasajeros Parque vs Accidentes')
Out[124]:
Text(0.5, 1.0, 'Gráfica análisis de Camiones pasajeros Parque vs Accidentes')

Se observo que tanto en el scatter de motos y camiones exiten valores atípicos es por ello que se aplicaron filtros para posteiormente observar las respectivas correlaciones.

In [125]:
motos_filtro = df_parque_accidentes[df_parque_accidentes['MOTOSParque']>0]
ax = sns.scatterplot(motos_filtro['MOTOSParque'],df_parque_accidentes['MOTOSAcci']);
ax.set(xlabel = 'Parque vehicular Motocicletas', ylabel = 'Número de accidentes')
ax.set_title('Gráfica análisis de Motocicleta Parque vs Accidentes')
Out[125]:
Text(0.5, 1.0, 'Gráfica análisis de Motocicleta Parque vs Accidentes')
In [126]:
camiones_filtro = df_parque_accidentes[df_parque_accidentes['CAMParque']<6000]
ax = sns.scatterplot(camiones_filtro['CAMParque'],df_parque_accidentes['CAMAcci']);
ax.set(xlabel = 'Parque vehicular Camiones pasajeros', ylabel = 'Número de accidentes')
ax.set_title('Gráfica análisis de Camiones pasajeros Parque vs Accidentes')
Out[126]:
Text(0.5, 1.0, 'Gráfica análisis de Camiones pasajeros Parque vs Accidentes')

Ya con las gráficas se obtuvieron las correlaciones entre las variables de parque vehicular y números de accidentes, obteniendo los siguientes resultados.

In [127]:
df_parque_accidentes['AUTOSParque'].corr(df_parque_accidentes['AUTOSAcci'])
Out[127]:
0.7390814900293179
In [128]:
motos_filtro['MOTOSParque'].corr(df_parque_accidentes['MOTOSAcci'])
Out[128]:
0.5722541735635367
In [129]:
camiones_filtro['CAMParque'].corr(df_parque_accidentes['CAMAcci'])
Out[129]:
0.6019599308623105

Se observa que entre el parque vehicular y el numero de accidentes exite una gran relación a partir del coeffiente obtenido, es por ello que se decide observar la relación entre todas las variables.

In [130]:
#Se eliminan las columnas innecesarias en nuestro análisis de correlaciones
filtro_motos = df_parque_accidentes['MOTOSParque']>0
df_total_filtro = df_parque_accidentes[filtro_motos]
df_total_filtro = df_total_filtro.reset_index(drop=True)
df_total_filtro_corr = df_total_filtro.drop(columns = ['ANIO','ID_MUNICIPIO','NOM_MUNICIPIO'])
df_total_filtro_corr.head()
Out[130]:
AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque
0 1008 51 246 222339 2543 1316
1 2034 77 535 363361 4452 2145
2 394 18 95 98138 1174 696
3 2703 129 684 384416 4905 4279
4 987 63 245 180009 2536 1711
In [131]:
df_total_filtro_corr.corr()
Out[131]:
AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque
AUTOSAcci 1.000000 0.858909 0.947065 0.778380 0.389401 0.507269
MOTOSAcci 0.858909 1.000000 0.756809 0.720660 0.572254 0.490596
CAMAcci 0.947065 0.756809 1.000000 0.770499 0.351014 0.612714
AUTOSParque 0.778380 0.720660 0.770499 1.000000 0.802682 0.619406
MOTOSParque 0.389401 0.572254 0.351014 0.802682 1.000000 0.516858
CAMParque 0.507269 0.490596 0.612714 0.619406 0.516858 1.000000

Con el fin de una mejor observación de la correlaciones entre las variables se hace uso de un heatmap.

In [132]:
plt.figure(figsize = (8,8))
ax = sns.heatmap(df_total_filtro_corr.corr(),annot=True, cmap = "YlGnBu",linewidths = 0.5)

Se observan correlaciones insospechadas, tales como la presente entre el número de accidentes en autos y en camiones de pasajeros, número de accidentes en autos y en motocicletas, etc., y se hizo uso de un pairplot para poder observar de mejor manera tales relaciones.

In [133]:
sns.pairplot(df_total_filtro_corr)
Out[133]:
<seaborn.axisgrid.PairGrid at 0x2bf0d222080>

Debido a que el objetivo es demostrar la relación entre el parque y el numero de accidentes se deja para trabajos futuros el análisis de las relaciones entre accidentes.

Regresiones lineales entre parque vehicular y accidentes

In [134]:
from sklearn.linear_model import LinearRegression
lr = LinearRegression()

Análisis Automovil

In [135]:
lr.fit(df_total_filtro['AUTOSParque'].to_frame(), df_total_filtro['AUTOSAcci'])
y_predict = lr.predict(df_total_filtro['AUTOSParque'].to_frame())
In [136]:
ax = sns.scatterplot(df_total_filtro['AUTOSParque'],y_predict);
sns.scatterplot(df_total_filtro['AUTOSParque'],df_total_filtro['AUTOSAcci'], ax=ax);
ax.set(xlabel = 'Parque vehicular Automoviles', ylabel = 'Número de accidentes');
ax.set_title('Gráfica regresión lineal de Automovil Parque vs Accidentes');

Podemos extraer la ecuación de la línea de nuestro modelo entrenado de esta manera. Y por lo tanto, nuestra función predictiva es la siguiente:

In [137]:
intercept = lr.intercept_
coefficient = lr.coef_[0]

print(f'y = {coefficient} * x + {intercept}')
y = 0.003773841102975018 * x + -8.43009901082155
In [138]:
efici = lr.score(df_total_filtro['AUTOSParque'].to_frame(), df_total_filtro['AUTOSAcci'])
print(f' Efectividad = {efici}')
 Efectividad = 0.605875297393174

Análisis Motocicletas

In [139]:
lr.fit(df_total_filtro['MOTOSParque'].to_frame(), df_total_filtro['MOTOSAcci'])
y_predict = lr.predict(df_total_filtro['MOTOSParque'].to_frame())
In [140]:
ax = sns.scatterplot(df_total_filtro['MOTOSParque'],y_predict);
sns.scatterplot(df_total_filtro['MOTOSParque'],df_total_filtro['MOTOSAcci'],ax = ax);
ax.set(xlabel = 'Parque vehicular Motocicletas', ylabel = 'Número de accidentes')
ax.set_title('Gráfica regresión lineal de Motocicleta Parque vs Accidentes')
Out[140]:
Text(0.5, 1.0, 'Gráfica regresión lineal de Motocicleta Parque vs Accidentes')

Podemos extraer la ecuación de la línea de nuestro modelo entrenado de esta manera. Y por lo tanto, nuestra función predictiva es la siguiente:

In [141]:
intercept = lr.intercept_
coefficient = lr.coef_[0]

print(f'y = {coefficient} * x + {intercept}')
y = 0.0021888885238465676 * x + 27.193053351419685
In [142]:
efici = lr.score(df_total_filtro['MOTOSParque'].to_frame(), df_total_filtro['MOTOSAcci'])
print(f' Efectividad = {efici}')
 Efectividad = 0.32747483916088627

Análisis Camiones de pasajeros

In [143]:
lr.fit(df_total_filtro['CAMParque'].to_frame(), df_total_filtro['CAMAcci'])
y_predict = lr.predict(df_total_filtro['CAMParque'].to_frame())
In [144]:
ax = sns.scatterplot(df_total_filtro['CAMParque'],y_predict);
sns.scatterplot(df_total_filtro['CAMParque'],df_total_filtro['CAMAcci'],ax = ax);
ax.set(xlabel = 'Parque vehicular Camiones', ylabel = 'Número de accidentes')
ax.set_title('Gráfica regresión lineal de Camiones de pasajeros Parque vs Accidentes')
Out[144]:
Text(0.5, 1.0, 'Gráfica regresión lineal de Camiones de pasajeros Parque vs Accidentes')

Podemos extraer la ecuación de la línea de nuestro modelo entrenado de esta manera. Y por lo tanto, nuestra función predictiva es la siguiente:

In [145]:
intercept = lr.intercept_
coefficient = lr.coef_[0]

print(f'y = {coefficient} * x + {intercept}')
y = 0.05886543817462139 * x + 175.46929661547026
In [146]:
efici = lr.score(df_total_filtro['CAMParque'].to_frame(), df_total_filtro['CAMAcci'])
print(f' Efectividad = {efici}')
 Efectividad = 0.37541783504238335

Se observa que de entrre todas las regresiones la mas efectiva es la eslablecida a partir del análisis de los automoviles, además, que según las regresiones todos gráficas son con crecimiento, hay que tomar en cuenta qu este análsis se realizo tomando en cuenta todos los datos registrados por cada alcaldia.

El siguiente análisis se realizó tomando en cuenta los datos obtenidos unicamente por año, para observar la relación de una manera general.

In [147]:
df_total_anio = df_total_filtro.groupby('ANIO')[['AUTOSAcci','MOTOSAcci','CAMAcci','AUTOSParque','MOTOSParque','CAMParque']].sum()
In [148]:
df_total_anio.head()
Out[148]:
AUTOSAcci MOTOSAcci CAMAcci AUTOSParque MOTOSParque CAMParque
ANIO
2012 23704 1067 5909 3787548 59097 31342
2013 21411 1007 5723 3929879 91267 31047
2014 18854 1078 5442 4421797 210020 31186
2015 15925 917 4760 4626870 260099 33189
2016 14646 936 4409 4806901 300587 32462

Análisis Automovil

In [149]:
lr.fit(df_total_anio['AUTOSParque'].to_frame(), df_total_anio['AUTOSAcci'])
y_predict = lr.predict(df_total_anio['AUTOSParque'].to_frame())
In [150]:
ax = sns.scatterplot(df_total_anio['AUTOSParque'],df_total_anio['AUTOSAcci']);
sns.scatterplot(df_total_anio['AUTOSParque'],y_predict,s=40,ax = ax);
ax.set(xlabel = 'Parque vehicular Automoviles', ylabel = 'Número de accidentes');
ax.set_title('Gráfica regresión lineal de Automovil Parque vs Accidentes anual');

Se observa una tendencia a la baja en relacion al parque vehicular analizando los datos de manera anual.

Análisis Motocicletas

In [151]:
lr.fit(df_total_anio['MOTOSParque'].to_frame(), df_total_anio['MOTOSAcci'])
y_predict = lr.predict(df_total_anio['MOTOSParque'].to_frame())
In [152]:
ax = sns.scatterplot(df_total_anio['MOTOSParque'],df_total_anio['MOTOSAcci']);
sns.scatterplot(df_total_anio['MOTOSParque'],y_predict,s=40, ax= ax);
ax.set(xlabel = 'Parque vehicular Motocicletas', ylabel = 'Número de accidentes')
ax.set_title('Gráfica regresión lineal de Motocicleta Parque vs Accidentes anual')
Out[152]:
Text(0.5, 1.0, 'Gráfica regresión lineal de Motocicleta Parque vs Accidentes anual')

Se observa una tendencia a la alza en relacion al parque vehicular analizando los datos de manera anual.

Análisis Camiones de pasajeros

In [153]:
lr.fit(df_total_anio['CAMParque'].to_frame(), df_total_anio['CAMAcci'])
y_predict = lr.predict(df_total_anio['CAMParque'].to_frame())
In [154]:
ax = sns.scatterplot(df_total_anio['CAMParque'],df_total_anio['CAMAcci']);
sns.scatterplot(df_total_anio['CAMParque'],y_predict,s=40,ax = ax);
ax.set(xlabel = 'Parque vehicular Camiones', ylabel = 'Número de accidentes')
ax.set_title('Gráfica regresión lineal de Camiones de pasajeros Parque vs Accidentes anual')
Out[154]:
Text(0.5, 1.0, 'Gráfica regresión lineal de Camiones de pasajeros Parque vs Accidentes anual')

Se observa una tendencia a la baja en relacion al parque vehicular analizando los datos de manera anual.

Por lo observado anteriormente se decidio realizar visulaciones de las tres alcaldias con mayor número de accidentes reportados.

Debido a que el objetivo es demostrar la relación entre el parque y el numero de accidentes se deja para trabajos futuros el análisis de las relaciones entre accidentes.

In [155]:
alcaldia1 = df_total_filtro['NOM_MUNICIPIO']=='Gustavo A. Madero'
alcaldia2 = df_total_filtro['NOM_MUNICIPIO']=='Iztapalapa'
alcaldia3 = df_total_filtro['NOM_MUNICIPIO']=='Cuauhtémoc'

df_total_alcaldia = df_total_filtro[(alcaldia1) | (alcaldia2) | (alcaldia3)].reset_index()
In [156]:
ax = sns.scatterplot(df_total_alcaldia['AUTOSParque'], df_total_alcaldia['AUTOSAcci'], hue=df_total_alcaldia['NOM_MUNICIPIO']);
ax.set(xlabel = 'Parque vehicular Automoviles', ylabel = 'Número de accidentes');
ax.set_title('Gráfica Automovil Parque vs Accidentes');
In [157]:
ax = sns.scatterplot(df_total_alcaldia['MOTOSParque'], df_total_alcaldia['MOTOSAcci'], hue=df_total_alcaldia['NOM_MUNICIPIO']);
ax.set(xlabel = 'Parque vehicular Motocicletas', ylabel = 'Número de accidentes');
ax.set_title('Gráfica de Motocicleta Parque vs Accidentes');
In [158]:
ax = sns.scatterplot(df_total_alcaldia['CAMParque'], df_total_alcaldia['CAMAcci'], hue=df_total_alcaldia['NOM_MUNICIPIO']);
ax.set(xlabel = 'Parque vehicular Camiones', ylabel = 'Número de accidentes');
ax.set_title('Gráfica de Camiones de pasajeros Parque vs Accidentes');

Se observa que en la parte de automovil las tres alcaldias presentan comportamientos similares tendiendo a la baja, mientras que en la parte de motocicletas la tendencia en un poco parecida entre ellas y por último en las observaciones de los camiones de pasajeros sus comportamietnos son parecidos a pesar de la diferencia entre el parque vehicular.

Se agregan las gráficas de los comportamientos de cada tipo de vehiculo por alcaldia para que el lector pueda observar con se comportan individualmente.

In [159]:
fig, axes = plt.subplots(4, 4, figsize=(25, 15));

indice = 0;

for i in range(0,4):
    for j in range(0,4):
        alcaldia = df_total_filtro['NOM_MUNICIPIO']==df_total_filtro['NOM_MUNICIPIO'].unique()[indice]
        sns.scatterplot(df_total_filtro[alcaldia]['AUTOSParque'],df_total_filtro[alcaldia]['AUTOSAcci'],ax=axes[i, j])
        axes[i, j].set(xlabel='', ylabel='', title=df_total_filtro['NOM_MUNICIPIO'].unique()[indice]);
        indice = indice+1
fig.suptitle('Graficas Automovil', fontsize=25);
In [160]:
fig, axes = plt.subplots(4, 4, figsize=(25, 15));

indice = 0;

for i in range(0,4):
    for j in range(0,4):
        alcaldia = df_total_filtro['NOM_MUNICIPIO']==df_total_filtro['NOM_MUNICIPIO'].unique()[indice]
        sns.scatterplot(df_total_filtro[alcaldia]['MOTOSParque'],df_total_filtro[alcaldia]['MOTOSAcci'],ax=axes[i, j]);
        axes[i, j].set(xlabel='', ylabel='', title=df_total_filtro['NOM_MUNICIPIO'].unique()[indice]);
        indice = indice+1 
fig.suptitle('Graficas Motocicletas', fontsize=25);
In [161]:
fig, axes = plt.subplots(4, 4, figsize=(25, 15));

indice = 0;

for i in range(0,4):
    for j in range(0,4):
        alcaldia = df_total_filtro['NOM_MUNICIPIO']==df_total_filtro['NOM_MUNICIPIO'].unique()[indice]
        sns.scatterplot(df_total_filtro[alcaldia]['CAMParque'],df_total_filtro[alcaldia]['CAMAcci'],ax=axes[i, j]);
        axes[i, j].set(xlabel='', ylabel='', title=df_total_filtro['NOM_MUNICIPIO'].unique()[indice]);
        indice = indice+1 
fig.suptitle('Graficas Camiones de pasajeros', fontsize=25);

Seccion de Conclusiones y Proyección del Análisis Inferencial

Para esta última parte y como se resalto en múltiples comentarios los análisis inferenciales deberán ir enfocados en evaluar 3 aspectos específicos.

El primer rubro será el análisis del impacto de los distintos factores o variables sobre los choques, para esto será necesario llevar a cabo análisis de regresión multivariable en los cuáles se puedan evaluar los coeficientes, así como las interacciones de estos factores. Dentro de las herramientas estadísticas que podremos utilizar para este análisis destacan ANOVA, K - Means, Random Forests, entre otros.

El segundo rubro será ahondar en el análisis comparativo con otros archivos de datos como lo es el parque vehicular, la cantidad de hombres y mujeres registrados, persona registradas por delegación, personas registradas por grupos de edad, entre otros. Los cuáles serán eficacez para eliminar ciertos tipos de sesgo que por ahora se tienen y que impiden un análisis más profundo de los factores determinates para la generación de un choque.

Como último rubro, será importante seguir enfocando hacía la predicción de choques bajo diferentes tipos de escenarios, para eto será útil efectuar métodos como las series de tiempo. asimismo y complementadno lo anterior estas predicciones podrán ayudar a también generar posibles análisis económetricos de la situación.

Finalmente, englobando todo este futuro desarrollo, estipulado sobre las base del análisis exploratorio que se genero, la propuesta final será diseñar estrategias que permitan mitigar los factores (causas raíz) que propician mayor número de choques. A manera de ejemplo, durante este primer análisis encontramos que a medida que incrementaba la hora del día, aumentaba el número de choques, y que el Viernes era el día con mayor número de choques registrados. Aunado a esto encontramos, qué alcaldías, erán las que tenían un reporte de mayor número de accidentes, por lo que, considerando estos tres factores, podriamos diseñar una medida de contigencía de alchólimetros mejor ubicados y distribuidos sobre las delegaciones con más concentración de choques y en horarios que quizas antes no se tenían contemplados, con esto probablemente reducir choques y consecuentemente reducir gasto público e indivdual. Esto claramente fue un somero esbozo del tipo de soluciones que podrían proponerse, siendo conscientes de que ese tipo de decisiones deberá contemplar también otros factores como movilidad en la zona, presupuesto de tránsito y vialidad, entre otros que los expertos en el tema considerarán, sin embargo, este ejercicio tenía como mera finalidad evidenciar el potencial de los resultados que pudiera llegar a tener este análisis y la utilidad sobre la problemática planteada al inicio del proyecto.

Modelo ARIMA

ARIMA es un modelo autorregresivo integrado de promedio móvil (acrónimo del inglés autoregressive integrated moving average) este modelo utiliza variaciones y regresiones de datos estadísticos con el fin de encontrar patrones para lograr efectuar una predicción futura del comportamiento de la serie.

En este caso específico se realizo un modelo ARIMA con el fin de evaluar el comportamiento del número de accidentes a lo largo de los años venideros, para ello se realizaron varias modificaciones a nuestro Data Frame principal "df_cdmx", a continuación se presenta la descripción detallada del desarrollo de este modelo.

Lo primero fue agrupar el número de accidentes por año y mes, para obtener una suficiente cantidad de datos que nos permitiera llevar a cabo el análisis, esto debido a que el análisis por años tenía unicamente 10 registros.

In [168]:
filtro_arima=df_cdmx.groupby("ANIO")["MES"].value_counts()
filtro_arima1=filtro_arima.reset_index(name="Numero_Acc")
filtro_arima2 = pd.DataFrame(filtro_arima1)
filtro_arima2
Out[168]:
ANIO MES Numero_Acc
0 2010 10 1414
1 2010 11 1355
2 2010 9 1326
3 2010 8 1324
4 2010 5 1249
... ... ... ...
115 2019 5 872
116 2019 2 850
117 2019 1 807
118 2019 4 784
119 2019 6 773

120 rows × 3 columns

Lo siguiente fue establecer como índice a las columnas de Año y Mes, asimismo ordenamos los meses (1-12) por año para proceder con la graficación del DF con el que estariamos trabajando.

In [169]:
filtro_arima3 = filtro_arima2.set_index(["ANIO","MES"])
filtro_arima3_1 = filtro_arima2.set_index(["ANIO"])
filtro_arima3.head(12)
Out[169]:
Numero_Acc
ANIO MES
2010 10 1414
11 1355
9 1326
8 1324
5 1249
3 1246
7 1246
6 1202
12 1201
4 1093
1 1039
2 1034
In [170]:
filtro_arima4 = filtro_arima3.sort_values(by=['ANIO','MES'])
filtro_arima4_1 = filtro_arima3_1.sort_values(by=['ANIO','MES'])
filtro_arima5 = pd.DataFrame(filtro_arima4)
filtro_arima5
Out[170]:
Numero_Acc
ANIO MES
2010 1 1039
2 1034
3 1246
4 1093
5 1249
... ... ...
2019 8 943
9 953
10 1027
11 939
12 915

120 rows × 1 columns

In [172]:
fig, ax = plt.subplots()
filtro_arima5.plot(ax=ax)
plt.show;

Lo siguiente fue llevar a cabo una análisis para identificar si necesitamos transformar nuestra Xt esto con el fin de eliminar la no estacionalidad en la media p en la heteroscedasticidad. Para ello utilizamos el Dicky-Füller, estableciendo una hipótesis que de no ser rechazada permitía continuar con el proceso sin necesidad de realizar el ajuste anteriormente mencionado. (P-value > .05 por lo tanto continuamos)

In [174]:
from statsmodels.tsa.stattools import adfuller
result = adfuller(filtro_arima5['Numero_Acc'])
print('ADF Statistic: {}'.format(result[0]))
print('p-value: {}'.format(result[1]))
print('Critical Values:')
for key, value in result[4].items():
    print('\t{}: {}'.format(key, value))
ADF Statistic: -0.6057470689856981
p-value: 0.8696781295804985
Critical Values:
	1%: -3.4936021509366793
	5%: -2.8892174239808703
	10%: -2.58153320754717

Definimos nuestro Train y Test set

In [175]:
train = filtro_arima5.iloc[0:100]
test = filtro_arima5.iloc[101:]

Utilizamos ARIMA del módulo statsmodels para evaluar el modelo de ajuste, el método, el análisis logarítmico y los componentes con sus respectivos coeficientes de autoregresión y promedios móviles

In [176]:
from statsmodels.tsa.arima_model import ARIMA
modelo=ARIMA(train['Numero_Acc'],order=(1,0,5))
modelo=modelo.fit()
modelo.summary()
C:\Users\Sergio\Anaconda3\lib\site-packages\statsmodels\tsa\base\tsa_model.py:579: ValueWarning:

An unsupported index was provided and will be ignored when e.g. forecasting.

Out[176]:
ARMA Model Results
Dep. Variable: Numero_Acc No. Observations: 100
Model: ARMA(1, 5) Log Likelihood -597.943
Method: css-mle S.D. of innovations 94.808
Date: Mon, 10 May 2021 AIC 1211.886
Time: 02:50:07 BIC 1232.727
Sample: 0 HQIC 1220.321
coef std err z P>|z| [0.025 0.975]
const 1122.0359 114.655 9.786 0.000 897.316 1346.756
ar.L1.Numero_Acc 0.9700 0.027 35.314 0.000 0.916 1.024
ma.L1.Numero_Acc -0.3410 0.130 -2.615 0.009 -0.597 -0.085
ma.L2.Numero_Acc 0.0119 0.142 0.084 0.933 -0.267 0.290
ma.L3.Numero_Acc -0.2805 0.177 -1.584 0.113 -0.628 0.067
ma.L4.Numero_Acc 0.0987 0.119 0.831 0.406 -0.134 0.332
ma.L5.Numero_Acc -0.0466 0.167 -0.279 0.781 -0.374 0.281
Roots
Real Imaginary Modulus Frequency
AR.1 1.0309 +0.0000j 1.0309 0.0000
MA.1 -0.8631 -1.2365j 1.5080 -0.3470
MA.2 -0.8631 +1.2365j 1.5080 0.3470
MA.3 1.3440 -0.0000j 1.3440 -0.0000
MA.4 1.2508 -2.3370j 2.6507 -0.1718
MA.5 1.2508 +2.3370j 2.6507 0.1718
In [180]:
inicio =len(train)
final = len(train) - len(test)
pred = modelo.predict(inicio = inicio , final = final,typ='levels').rename('ARIMA Predictions')
pred.plot(legend=True);
test['Numero_Acc'].plot(legend=True)
Out[180]:
<AxesSubplot:xlabel='ANIO,MES'>

Pese a que en el análisis decriptivo del modelo de ARIMA en donde se habían identificado la raíces MA.1 - MA.5 (Moving Averages), con coeficientes ue se muestran en el indicador como significativos el AR.1 pudiera ser indientificado como no significativo con un valor de z de 35, en este caso resultaría efectivo analizar de nuevo nuestros sets de entrenamiento y prueba y el modelo ARMA (1,5).

In [ ]: